Minor - merge with 1.11.x

pull/2818/head
Julio Montoya 7 years ago
parent e75dc396c9
commit d7c14e8606
  1. 11
      main/admin/user_edit.php
  2. 13
      main/announcements/announcements.php
  3. 3
      main/auth/courses.php
  4. 11
      main/auth/profile.php
  5. 11
      main/calendar/agenda.php
  6. 2
      main/calendar/agenda_js.php
  7. 13
      main/calendar/agenda_list.php
  8. 11
      main/chat/chat.php
  9. 20
      main/course_description/index.php
  10. 13
      main/course_home/course_home.php
  11. 7
      main/document/showinframes.php
  12. 47
      main/exercise/exercise.class.php
  13. 66
      main/exercise/exercise.php
  14. 12
      main/exercise/exercise_admin.php
  15. 4
      main/exercise/exercise_report.php
  16. 9
      main/exercise/exercise_result.php
  17. 54
      main/exercise/exercise_show.php
  18. 13
      main/exercise/exercise_submit.php
  19. 29
      main/exercise/fill_blanks.class.php
  20. 2
      main/exercise/freeanswer.class.php
  21. 2
      main/exercise/hotspot.class.php
  22. 4
      main/exercise/hotspot_admin.inc.php
  23. 25
      main/exercise/hotspot_answers.as.php
  24. 54
      main/exercise/overview.php
  25. 23
      main/exercise/question.class.php
  26. 11
      main/exercise/result.php
  27. 2
      main/exercise/unique_answer.class.php
  28. 4
      main/extra/print_myStudents.php
  29. 6
      main/forum/editthread.php
  30. 139
      main/forum/forumfunction.inc.php
  31. 12
      main/forum/index.php
  32. 10
      main/forum/newthread.php
  33. 10
      main/forum/reply.php
  34. 10
      main/forum/viewforum.php
  35. 10
      main/forum/viewforumcategory.php
  36. 11
      main/forum/viewthread.php
  37. 23
      main/gradebook/gradebook_add_cat.php
  38. 23
      main/gradebook/gradebook_add_eval.php
  39. 30
      main/gradebook/gradebook_add_link.php
  40. 17
      main/gradebook/gradebook_display_summary.php
  41. 18
      main/gradebook/gradebook_edit_all.php
  42. 22
      main/gradebook/gradebook_edit_cat.php
  43. 12
      main/gradebook/gradebook_edit_eval.php
  44. 11
      main/gradebook/gradebook_edit_link.php
  45. 58
      main/gradebook/index.php
  46. 4
      main/gradebook/lib/be/category.class.php
  47. 4
      main/gradebook/lib/be/evaluation.class.php
  48. 2
      main/gradebook/lib/fe/displaygradebook.php
  49. 11
      main/gradebook/my_certificates.php
  50. 1
      main/group/group_category.php
  51. 9
      main/inc/ajax/agenda.ajax.php
  52. 9
      main/inc/ajax/course.ajax.php
  53. 12
      main/inc/ajax/course_chat.ajax.php
  54. 1
      main/inc/ajax/course_home.ajax.php
  55. 10
      main/inc/ajax/social.ajax.php
  56. 36
      main/inc/lib/TicketManager.php
  57. 6
      main/inc/lib/agenda.lib.php
  58. 18
      main/inc/lib/api.lib.php
  59. 63
      main/inc/lib/attendance.lib.php
  60. 9
      main/inc/lib/banner.lib.php
  61. 2
      main/inc/lib/blog.lib.php
  62. 3
      main/inc/lib/course.lib.php
  63. 8
      main/inc/lib/course_home.lib.php
  64. 91
      main/inc/lib/document.lib.php
  65. 68
      main/inc/lib/events.lib.php
  66. 53
      main/inc/lib/exercise.lib.php
  67. 100
      main/inc/lib/exercise_show_functions.lib.php
  68. 1
      main/inc/lib/fixlinks.js
  69. 17
      main/inc/lib/online.inc.php
  70. 8
      main/inc/lib/pdf.lib.php
  71. 3
      main/inc/lib/pear/HTML/QuickForm/advmultiselect.php
  72. 55
      main/inc/lib/social.lib.php
  73. 6
      main/inc/lib/sortable_table.class.php
  74. 36
      main/inc/lib/template.lib.php
  75. 349
      main/inc/lib/tracking.lib.php
  76. 30
      main/inc/lib/usergroup.lib.php
  77. 66
      main/inc/lib/usermanager.lib.php
  78. 2
      main/inc/lib/webservices/Rest.php
  79. 232
      main/lp/learnpath.class.php
  80. 62
      main/lp/learnpathItem.class.php
  81. 9
      main/lp/lp_ajax_save_item.php
  82. 57
      main/lp/lp_ajax_switch_item.php
  83. 2
      main/lp/lp_content.php
  84. 106
      main/lp/lp_controller.php
  85. 19
      main/lp/lp_edit.php
  86. 101
      main/lp/lp_list.php
  87. 49
      main/lp/lp_view.php
  88. 92
      main/lp/scorm_api.php
  89. 11
      main/messages/inbox.php
  90. 14
      main/messages/new_message.php
  91. 11
      main/messages/outbox.php
  92. 11
      main/messages/view_message.php
  93. 11
      main/mySpace/index.php
  94. 654
      main/mySpace/myStudents.php
  95. 14
      main/mySpace/session.php
  96. 14
      main/mySpace/student.php
  97. 14
      main/mySpace/users.php
  98. 11
      main/notebook/index.php
  99. 142
      main/survey/fillsurvey.php
  100. 5
      main/survey/preview.php
  101. Some files were not shown because too many files have changed in this diff Show More

@ -457,10 +457,15 @@ if ($form->validate()) {
$template
);
if (isset($user['student_boss'])) {
UserManager::subscribeUserToBossList($user_id, $user['student_boss']);
}
$studentBossListSent = isset($user['student_boss']) ? $user['student_boss'] : [];
UserManager::subscribeUserToBossList(
$user_id,
$studentBossListSent,
true
);
$currentUserId = api_get_user_id();
$userObj = api_get_user_entity($user_id);
UserManager::add_user_as_admin($userObj);

@ -93,6 +93,17 @@ $homeUrl = api_get_self().'?action=list&'.api_get_cidreq();
$content = '';
$searchFormToString = '';
$logInfo = [
'tool' => TOOL_ANNOUNCEMENT,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'action_details' => '',
'current_id' => (int) $announcement_id,
'info' => '',
];
Event::registerLog($logInfo);
switch ($action) {
case 'move':
if (!$allowToEdit) {
@ -337,7 +348,7 @@ switch ($action) {
}
break;
case 'delete_attachment':
$id = $_GET['id_attach'];
$id = (int) $_GET['id_attach'];
if (api_is_allowed_to_edit()) {
AnnouncementManager::delete_announcement_attachment_file($id);

@ -30,10 +30,9 @@ if (api_get_setting('course_catalog_published') !== 'true') {
}
//For students
$user_can_view_page = true;
if (api_get_setting('allow_students_to_browse_courses') === 'false') {
$user_can_view_page = false;
} else {
$user_can_view_page = true;
}
//For teachers/admins

@ -20,6 +20,17 @@ if (api_get_setting('allow_social_tool') === 'true') {
$this_section = SECTION_SOCIAL;
}
$logInfo = [
'tool' => 'profile',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $this_section,
'action_details' => '',
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
$profileList = (array) api_get_setting('profile');
$_user = api_get_user_info();

@ -15,7 +15,7 @@ if (!empty($course_info)) {
api_protect_course_script(true);
}
$action = isset($_GET['action']) ? $_GET['action'] : null;
$action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : null;
$this_section = SECTION_COURSES;
$url = null;
@ -29,6 +29,15 @@ if (empty($action)) {
exit;
}
$logInfo = [
'tool' => TOOL_CALENDAR_EVENT,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'info' => '',
];
Event::registerLog($logInfo);
$group_id = api_get_group_id();
$groupInfo = GroupManager::get_group_properties($group_id);
$eventId = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;

@ -180,7 +180,7 @@ if ($type == 'course' && !empty($session_id)) {
$agendaColors = array_merge(
[
'platform' => '#ff6258', //red
'platform' => 'red', //red
'course' => '#458B00', //green
'group' => '#A0522D', //siena
'session' => '#00496D', // kind of green

@ -6,6 +6,17 @@
*/
require_once __DIR__.'/../inc/global.inc.php';
$action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : 'calendar_list';
$logInfo = [
'tool' => TOOL_CALENDAR_EVENT,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'info' => '',
];
Event::registerLog($logInfo);
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$interbreadcrumb[] = [
@ -83,7 +94,7 @@ $tpl->assign('agenda_actions', $actions);
$tpl->assign('is_allowed_to_edit', api_is_allowed_to_edit());
if (api_is_allowed_to_edit()) {
if (isset($_GET['action']) && $_GET['action'] == 'change_visibility') {
if ($action == 'change_visibility') {
$courseInfo = api_get_course_info();
$courseCondition = '';
// This happens when list agenda is not inside a course

@ -9,6 +9,17 @@ api_protect_course_script(true);
Event::event_access_tool(TOOL_CHAT);
$logInfo = [
'tool' => TOOL_CHAT,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'start',
'action_details' => 'start-chat',
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
// View
$externalCSS = [
'jquery-emojiarea/jquery.emojiarea.css',

@ -18,15 +18,19 @@ define('ADD_BLOCK', 8);
// current section
$this_section = SECTION_COURSES;
$action = !empty($_GET['action']) ? Security::remove_XSS($_GET['action']) : 'listing';
// protect a course script
api_protect_course_script(true);
$logInfo = [
'tool' => TOOL_COURSE_DESCRIPTION,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'info' => '',
];
Event::registerLog($logInfo);
// get actions
$actions = ['listing', 'add', 'edit', 'delete', 'history'];
$action = 'listing';
if (isset($_GET['action']) && in_array($_GET['action'], $actions)) {
$action = $_GET['action'];
}
api_protect_course_script(true);
$description_type = '';
if (isset($_GET['description_type'])) {
@ -84,9 +88,6 @@ if (in_array($action, ['add', 'edit', 'delete']) &&
// Actions to controller
switch ($action) {
case 'listing':
$descriptionController->listing();
break;
case 'history':
$descriptionController->listing(true);
break;
@ -99,6 +100,7 @@ switch ($action) {
case 'delete':
$descriptionController->destroy($id);
break;
case 'listing':
default:
$descriptionController->listing();
}

@ -138,7 +138,9 @@ if ($isSpecialCourse) {
}
}
if (isset($_GET['action']) && $_GET['action'] == 'subscribe') {
$action = !empty($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
if ($action == 'subscribe') {
if (Security::check_token('get')) {
Security::clear_token();
$result = CourseManager::autoSubscribeToCourse($course_code);
@ -162,6 +164,15 @@ if (!isset($coursesAlreadyVisited[$course_code])) {
Session::write('coursesAlreadyVisited', $coursesAlreadyVisited);
}
$logInfo = [
'tool' => 'course-main',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'info' => '',
];
Event::registerLog($logInfo);
/*Auto launch code */
$autoLaunchWarning = '';
$showAutoLaunchLpWarning = false;

@ -165,9 +165,7 @@ if (api_is_course_admin()) {
$frameheight = 165;
}
$js_glossary_in_documents = '
setFrameReady("mainFrame");
';
$frameReady = Display::getFrameReadyBlock('top.mainFrame');
$web_odf_supported_files = DocumentManager::get_web_odf_extension_list();
// PDF should be displayed with viewerJS
@ -239,8 +237,7 @@ if (!$playerSupported && $execute_iframe) {
// Fixes the content height of the frame
window.onload = function() {
updateContentHeight();
'.$js_glossary_in_documents.'
'.$frameReady.'
}
</script>';
}

@ -1935,7 +1935,6 @@ class Exercise
'2',
['id' => 'result_disabled_2']
);
$radios_results_disabled[] = $form->createElement(
'radio',
'results_disabled',
@ -1944,6 +1943,14 @@ class Exercise
'4',
['id' => 'result_disabled_4']
);
$radios_results_disabled[] = $form->createElement(
'radio',
'results_disabled',
null,
get_lang('DontShowScoreOnlyWhenUserFinishesAllAttemptsButShowFeedbackEachAttempt'),
'5',
['id' => 'result_disabled_5', 'onclick' => 'check_results_disabled()']
);
$form->addGroup(
$radios_results_disabled,
@ -2014,6 +2021,7 @@ class Exercise
null,
[get_lang('FeedbackType'), get_lang('FeedbackDisplayOptions')]
);
$radios_results_disabled = [];
$radios_results_disabled[] = $form->createElement(
'radio',
@ -2039,6 +2047,7 @@ class Exercise
'2',
['id' => 'result_disabled_2', 'onclick' => 'check_results_disabled()']
);
$form->addGroup($radios_results_disabled, null, get_lang('ShowResultsToStudents'), '');
// Type of questions disposition on page
@ -2078,6 +2087,9 @@ class Exercise
'2',
['id' => 'result_disabled_2', 'onclick' => 'check_results_disabled()']
);
$form->addGroup($radios_results_disabled, null, get_lang('ShowResultsToStudents'), '');
$result_disable_group = $form->addGroup(
$radios_results_disabled,
null,
@ -3482,7 +3494,6 @@ class Exercise
if ($debug) {
error_log('Start answer loop ');
}
for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
$answer = $objAnswerTmp->selectAnswer($answerId);
$answerComment = $objAnswerTmp->selectComment($answerId);
@ -3760,7 +3771,8 @@ class Exercise
$str = $answerFromDatabase = Database::result($result, 0, 'answer');
}
if ($saved_results == false && strpos($answerFromDatabase, 'font color') !== false) {
// if ($saved_results == false && strpos($answerFromDatabase, 'font color') !== false) {
if (false) {
// the question is encoded like this
// [A] B [C] D [E] F::10,10,10@1
// number 1 before the "@" means that is a switchable fill in blank question
@ -4617,7 +4629,7 @@ class Exercise
if ($debug) {
error_log('Showing questions $from '.$from);
}
if ($from == 'exercise_result') {
if ($from === 'exercise_result') {
//display answers (if not matching type, or if the answer is correct)
if (!in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE]) ||
$answerCorrect
@ -4748,7 +4760,6 @@ class Exercise
// force to show whether the choice is correct or not
$showTotalScoreAndUserChoicesInLastAttempt = true;
ExerciseShowFunctions::display_hotspot_answer(
$feedback_type,
++$correctAnswerId,
@ -4888,7 +4899,6 @@ class Exercise
if ($debug > 0) {
error_log(__LINE__.' - answerId is >1 so we\'re probably in OAR', 0);
}
$inter = $result['success'];
$delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId);
$poly_answer = convert_coordinates($delineation_cord, '|');
$max_coord = poly_get_max($poly_user, $poly_answer);
@ -4948,7 +4958,6 @@ class Exercise
if ($debug) {
error_log('Showing questions $from '.$from);
}
switch ($answerType) {
case UNIQUE_ANSWER:
case UNIQUE_ANSWER_IMAGE:
@ -5256,12 +5265,7 @@ class Exercise
}
if ($debug > 0) {
error_log(__LINE__.' - answerId is >1 so we\'re probably in OAR', 0);
}
//check the intersection between the oar and the user
//echo 'user'; print_r($x_user_list); print_r($y_user_list);
//echo 'official';print_r($x_list);print_r($y_list);
//$result = get_intersection_data($x_list,$y_list,$x_user_list,$y_user_list);
$inter = $result['success'];
}
$delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId);
$poly_answer = convert_coordinates($delineation_cord, '|');
$max_coord = poly_get_max($poly_user, $poly_answer);
@ -5782,7 +5786,7 @@ class Exercise
}
} else {
if ($debug) {
error_log("Empty: exerciseResultCoordinates");
error_log('Empty: exerciseResultCoordinates');
}
}
Event::saveQuestionAttempt($questionScore, implode('|', $answer), $quesId, $exeId, 0, $this->id);
@ -7354,15 +7358,9 @@ class Exercise
}
$attributes = ['id' => 'remind_list['.$questionId.']'];
if (is_array($remindList) && in_array($questionId, $remindList)) {
//$attributes['checked'] = 1;
//$remind_highlight = ' remind_highlight ';
}
// Showing the question
$exercise_actions = null;
echo '<a id="questionanchor'.$questionId.'"></a><br />';
echo '<div id="question_div_'.$questionId.'" class="main_question '.$remind_highlight.'" >';
@ -7620,8 +7618,8 @@ class Exercise
*/
public function getExercisesByCourseSession($courseId, $sessionId)
{
$courseId = intval($courseId);
$sessionId = intval($sessionId);
$courseId = (int) $courseId;
$sessionId = (int) $sessionId;
$tbl_quiz = Database::get_course_table(TABLE_QUIZ_TEST);
$sql = "SELECT * FROM $tbl_quiz cq
@ -7655,7 +7653,9 @@ class Exercise
return [];
}
$sessionId = intval($sessionId);
$sessionId = (int) $sessionId;
$courseId = (int) $courseId;
$ids = is_array($quizId) ? $quizId : [$quizId];
$ids = array_map('intval', $ids);
$ids = implode(',', $ids);
@ -7822,7 +7822,6 @@ class Exercise
);
$corrects = [];
foreach ($attempts as $attempt) {
foreach ($attempt['question_list'] as $answers) {
foreach ($answers as $answer) {

@ -50,7 +50,7 @@ $TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$TBL_TRACK_EXERCISES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
// document path
$documentPath = api_get_path(SYS_COURSE_PATH).$courseInfo['path']."/document";
$documentPath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
// picture path
$picturePath = $documentPath.'/images';
// audio path
@ -62,8 +62,7 @@ $exercisePath = api_get_self();
$exfile = explode('/', $exercisePath);
$exfile = strtolower($exfile[sizeof($exfile) - 1]);
$exercisePath = substr($exercisePath, 0, strpos($exercisePath, $exfile));
$exercisePath = $exercisePath."exercise.php";
$exercisePath = $exercisePath.'exercise.php';
// Clear the exercise session
Session::erase('objExercise');
@ -82,9 +81,9 @@ $choice = isset($_REQUEST['choice']) ? Security::remove_XSS($_REQUEST['choice'])
$hpchoice = isset($_REQUEST['hpchoice']) ? Security::remove_XSS($_REQUEST['hpchoice']) : null;
$exerciseId = isset($_REQUEST['exerciseId']) ? (int) $_REQUEST['exerciseId'] : null;
$file = isset($_REQUEST['file']) ? Database::escape_string($_REQUEST['file']) : null;
$learnpath_id = isset($_REQUEST['learnpath_id']) ? intval($_REQUEST['learnpath_id']) : null;
$learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? intval($_REQUEST['learnpath_item_id']) : null;
$page = isset($_REQUEST['page']) ? intval($_REQUEST['page']) : null;
$learnpath_id = isset($_REQUEST['learnpath_id']) ? (int) $_REQUEST['learnpath_id'] : null;
$learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? (int) $_REQUEST['learnpath_item_id'] : null;
$page = isset($_REQUEST['page']) ? (int) $_REQUEST['page'] : null;
if ($page < 0) {
$page = 1;
@ -106,7 +105,7 @@ if (api_get_course_setting('enable_exercise_auto_launch') == 1 &&
$nameTools = get_lang('Exercises');
$errorXmlExport = null;
if ($is_allowedToEdit && !empty($choice) && $choice == 'exportqti2') {
if ($is_allowedToEdit && !empty($choice) && $choice === 'exportqti2') {
require_once api_get_path(SYS_CODE_PATH).'exercise/export/qti2/qti2_export.php';
$export = export_exercise_to_qti($exerciseId, true);
@ -142,10 +141,8 @@ if ($is_allowedToEdit && !empty($choice) && $choice == 'exportqti2') {
if ($origin != 'learnpath') {
//so we are not in learnpath tool
Display :: display_header($nameTools, get_lang('Exercise'));
if (isset($_GET['message'])) {
if (in_array($_GET['message'], ['ExerciseEdited'])) {
echo Display::return_message(get_lang($_GET['message']), 'confirmation');
}
if (isset($_GET['message']) && in_array($_GET['message'], ['ExerciseEdited'])) {
echo Display::return_message(get_lang('ExerciseEdited'), 'confirmation');
}
} else {
Display::display_reduced_header();
@ -153,6 +150,16 @@ if ($origin != 'learnpath') {
Event::event_access_tool(TOOL_QUIZ);
$logInfo = [
'tool' => TOOL_QUIZ,
'tool_id' => (int) $exerciseId,
'tool_id_detail' => 0,
'action' => isset($_REQUEST['learnpath_id']) ? 'learnpath_id' : '',
'action_details' => isset($_REQUEST['learnpath_id']) ? (int) $_REQUEST['learnpath_id'] : '',
'current_id' => 0,
];
Event::registerLog($logInfo);
// Tool introduction
Display::display_introduction_section(TOOL_QUIZ);
@ -376,7 +383,7 @@ if ($is_allowedToEdit) {
break;
case 'disable': // disables an exercise
$newVisibilityStatus = "0"; //"invisible"
$newVisibilityStatus = '0'; //"invisible"
$query = "SELECT id FROM $TBL_DOCUMENT
WHERE c_id = $courseId AND path='".Database :: escape_string($file)."'";
$res = Database::query($query);
@ -451,14 +458,15 @@ if ($is_allowedToEdit) {
$res = Database::query($sql);
$hp_count = Database :: num_rows($res);
} else {
$sql = "SELECT * FROM $TBL_DOCUMENT d, $TBL_ITEM_PROPERTY ip
$sql = "SELECT * FROM $TBL_DOCUMENT d
INNER JOIN $TBL_ITEM_PROPERTY ip
ON (d.id = ip.ref AND d.c_id = ip.c_id)
WHERE
d.id = ip.ref AND
ip.tool = '".TOOL_DOCUMENT."' AND
d.path LIKE '".Database :: escape_string($uploadPath.'/%/%')."' AND
ip.visibility ='1' AND
d.c_id = ".$courseId." AND
ip.c_id = ".$courseId;
d.c_id = $courseId AND
ip.c_id = $courseId";
$res = Database::query($sql);
$hp_count = Database :: num_rows($res);
}
@ -527,7 +535,6 @@ if ($total > $limit) {
}
$i = 1;
$online_icon = Display::return_icon(
'online.png',
get_lang('Visible'),
@ -541,7 +548,6 @@ $offline_icon = Display::return_icon(
$exerciseList = [];
$list_ordered = null;
while ($row = Database :: fetch_array($result, 'ASSOC')) {
$exerciseList[$row['iid']] = $row;
}
@ -966,9 +972,9 @@ if (!empty($exerciseList)) {
$my_exercise_id,
$random_number_of_question
);
$number_of_questions = $nbQuestionsTotal." ";
$number_of_questions .= ($nbQuestionsTotal > 1) ? get_lang("QuestionsLowerCase") : get_lang("QuestionLowerCase");
$number_of_questions .= " - ";
$number_of_questions = $nbQuestionsTotal.' ';
$number_of_questions .= ($nbQuestionsTotal > 1) ? get_lang('QuestionsLowerCase') : get_lang('QuestionLowerCase');
$number_of_questions .= ' - ';
$number_of_questions .= min(TestCategory::getNumberMaxQuestionByCat($my_exercise_id), $random_number_of_question).' '.get_lang('QuestionByCategory');
} else {
$random_label = ' ('.get_lang('Random').') ';
@ -981,10 +987,6 @@ if (!empty($exerciseList)) {
} else {
$number_of_questions = $rowi;
}
//Attempts
//$attempts = ExerciseLib::get_count_exam_results($row['id']).' '.get_lang('Attempts');
//$item .= Display::tag('td',$attempts);
$item .= Display::tag('td', $number_of_questions);
} else {
// Student only.
@ -1064,10 +1066,18 @@ if (!empty($exerciseList)) {
$start_time = api_strtotime($row['start_time'], 'UTC');
$end_time = api_strtotime($row['end_time'], 'UTC');
if ($today < $start_time) {
$attempt_text = sprintf(get_lang('ExerciseWillBeActivatedFromXToY'), api_convert_and_format_date($row['start_time']), api_convert_and_format_date($row['end_time']));
$attempt_text = sprintf(
get_lang('ExerciseWillBeActivatedFromXToY'),
api_convert_and_format_date($row['start_time']),
api_convert_and_format_date($row['end_time'])
);
} else {
if ($today > $end_time) {
$attempt_text = sprintf(get_lang('ExerciseWasActivatedFromXToY'), api_convert_and_format_date($row['start_time']), api_convert_and_format_date($row['end_time']));
$attempt_text = sprintf(
get_lang('ExerciseWasActivatedFromXToY'),
api_convert_and_format_date($row['start_time']),
api_convert_and_format_date($row['end_time'])
);
}
}
} else {
@ -1101,7 +1111,6 @@ if (!empty($exerciseList)) {
$attempt_text = get_lang('NotAttempted');
}
} else {
//$attempt_text = get_lang('CantShowResults');
$attempt_text = '-';
}
}
@ -1177,7 +1186,6 @@ if ($is_allowedToEdit) {
}
$result = Database::query($sql);
while ($row = Database :: fetch_array($result, 'ASSOC')) {
$attribute['path'][] = $row['path'];
$attribute['visibility'][] = $row['visibility'];

@ -172,12 +172,12 @@ if ($form->validate()) {
}
$nameTools = get_lang('ExerciseManagement');
$interbreadcrumb[] = [
"url" => 'exercise.php?'.api_get_cidreq(),
'url' => 'exercise.php?'.api_get_cidreq(),
'name' => get_lang('Exercises'),
];
$interbreadcrumb[] = [
"url" => 'admin.php?exerciseId='.$objExercise->id.'&'.api_get_cidreq(),
"name" => $objExercise->selectTitle(true),
'url' => 'admin.php?exerciseId='.$objExercise->id.'&'.api_get_cidreq(),
'name' => $objExercise->selectTitle(true),
];
Display::display_header($nameTools, get_lang('Exercise'));
@ -190,12 +190,14 @@ if ($form->validate()) {
} else {
if (!empty($_GET['lp_id']) || !empty($_POST['lp_id'])) {
if (!empty($_POST['lp_id'])) {
$lp_id = intval($_POST['lp_id']);
$lp_id = $_POST['lp_id'];
//TODO:this remains to be implemented after press the first post
} else {
$lp_id = intval($_GET['lp_id']);
$lp_id = $_GET['lp_id'];
}
$lp_id = (int) $lp_id;
echo "<a href=\"../lp/lp_controller.php?".api_get_cidreq()."&gradebook=&action=add_item&type=step&lp_id=".$lp_id."#resource_tab-2\">".Display::return_icon('back.png', get_lang("BackTo").' '.get_lang("LearningPaths"), '', ICON_SIZE_MEDIUM)."</a>";
Display::return_icon('back.png', get_lang("BackTo").' '.get_lang("LearningPaths"), '', ICON_SIZE_MEDIUM)."</a>";
} else {
echo '<a href="exercise.php?'.api_get_cidreq().'">'.
Display::return_icon('back.png', get_lang('BackToExercisesList'), '', ICON_SIZE_MEDIUM).

@ -198,7 +198,7 @@ if (isset($_REQUEST['comments']) &&
}
for ($i = 0; $i < $loop_in_track; $i++) {
$my_marks = isset($_POST['marks_'.$array_content_id_exe[$i]]) ? $_POST['marks_'.$array_content_id_exe[$i]] : 0;
$my_marks = isset($_POST['marks_'.$array_content_id_exe[$i]]) ? $_POST['marks_'.$array_content_id_exe[$i]] : '';
$my_comments = '';
if (isset($_POST['comments_'.$array_content_id_exe[$i]])) {
$my_comments = $_POST['comments_'.$array_content_id_exe[$i]];
@ -216,7 +216,6 @@ if (isset($_REQUEST['comments']) &&
['question_id = ? AND exe_id = ?' => [$my_questionid, $id]]
);
$sessionId = api_get_session_id();
$params = [
'exe_id' => $id,
'question_id' => $my_questionid,
@ -224,7 +223,6 @@ if (isset($_REQUEST['comments']) &&
'insert_date' => api_get_utc_datetime(),
'author' => api_get_user_id(),
'teacher_comment' => $my_comments,
'session_id' => $sessionId,
];
Database::insert($TBL_TRACK_ATTEMPT_RECORDING, $params);
}

@ -48,10 +48,10 @@ if (empty($objExercise)) {
$objExercise = new Exercise();
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
if (!empty($exercise_stat_info) && isset($exercise_stat_info['exe_exo_id'])) {
header("Location: overview.php?exerciseId=".$exercise_stat_info['exe_exo_id'].'&'.api_get_cidreq());
header('Location: overview.php?exerciseId='.$exercise_stat_info['exe_exo_id'].'&'.api_get_cidreq());
exit;
}
api_not_allowed();
api_not_allowed(true);
}
if (api_is_in_gradebook()) {
@ -64,8 +64,8 @@ if (api_is_in_gradebook()) {
$nameTools = get_lang('Exercises');
$interbreadcrumb[] = [
"url" => "exercise.php?".api_get_cidreq(),
"name" => get_lang('Exercises'),
'url' => 'exercise.php?'.api_get_cidreq(),
'name' => get_lang('Exercises'),
];
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'hotspot/js/hotspot.js"></script>';
@ -218,7 +218,6 @@ if ($origin != 'learnpath') {
Session::erase('duration_time_previous');
Session::erase('duration_time');
}
Session::write('attempt_remaining', $remainingMessage);
// Record the results in the learning path, using the SCORM interface (API)

@ -88,22 +88,28 @@ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
$courseInfo = api_get_course_info();
$sessionId = api_get_session_id();
$is_allowedToEdit = api_is_allowed_to_edit(null, true) ||
$is_allowedToEdit =
api_is_allowed_to_edit(null, true) ||
api_is_course_tutor() ||
api_is_session_admin() ||
api_is_drh() ||
api_is_student_boss();
if (!empty($sessionId) && !$is_allowedToEdit) {
if (api_is_course_session_coach(
$currentUserId,
api_get_course_int_id(),
$sessionId
)) {
if (!api_coach_can_edit_view_results(api_get_course_int_id(), $sessionId)
) {
if (!api_coach_can_edit_view_results(api_get_course_int_id(), $sessionId)) {
api_not_allowed($printHeaders);
}
}
} else {
if (!$is_allowedToEdit) {
api_not_allowed($printHeaders);
}
}
$allowCoachFeedbackExercises = api_get_setting('allow_coach_feedback_exercises') === 'true';
@ -122,7 +128,7 @@ if (empty($objExercise)) {
$objExercise->read($exercise_id);
}
$feedback_type = $objExercise->feedback_type;
//Only users can see their own results
// Only users can see their own results
if (!$is_allowedToEdit) {
if ($student_id != $currentUserId) {
api_not_allowed($printHeaders);
@ -230,22 +236,25 @@ $showTotalScoreAndUserChoicesInLastAttempt = true;
if (!empty($track_exercise_info)) {
// if the results_disabled of the Quiz is 1 when block the script
$result_disabled = $track_exercise_info['results_disabled'];
if ($result_disabled == RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS) {
$show_results = false;
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
$show_results = false;
$show_only_total_score = true;
if ($origin != 'learnpath') {
if ($currentUserId == $student_id) {
echo Display::return_message(
get_lang('ThankYouForPassingTheTest'),
'warning',
false
);
switch ($result_disabled) {
case RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS:
$show_results = false;
break;
case RESULT_DISABLE_SHOW_SCORE_ONLY:
$show_results = false;
$show_only_total_score = true;
if ($origin != 'learnpath') {
if ($currentUserId == $student_id) {
echo Display::return_message(
get_lang('ThankYouForPassingTheTest'),
'warning',
false
);
}
}
}
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
break;
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$attempts = Event::getExerciseResultsByUser(
$currentUserId,
$objExercise->id,
@ -267,6 +276,7 @@ if (!empty($track_exercise_info)) {
// Last attempt not reach don't show score/feedback
$showTotalScoreAndUserChoicesInLastAttempt = false;
}
break;
}
} else {
echo Display::return_message(get_lang('CantViewResults'), 'warning');
@ -369,6 +379,10 @@ if (!empty($maxEditors) && count($questionList) > $maxEditors) {
}
$objExercise->export = $action === 'export';
$arrid = [];
$arrmarks = [];
$strids = '';
$marksid = '';
$countPendingQuestions = 0;
foreach ($questionList as $questionId) {
@ -388,7 +402,6 @@ foreach ($questionList as $questionId) {
// Start buffer
ob_start();
if ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
$choice = [];
}
@ -1168,5 +1181,4 @@ unset($questionList);
Session::erase('exerciseResult');
unset($exerciseResult);
Session::erase('calculatedAnswerId');

@ -93,6 +93,17 @@ $current_question = isset($_REQUEST['num']) ? intval($_REQUEST['num']) : null;
$currentAnswer = isset($_REQUEST['num_answer']) ? intval($_REQUEST['num_answer']) : null;
$endExercise = isset($_REQUEST['end_exercise']) && $_REQUEST['end_exercise'] == 1 ? true : false;
$logInfo = [
'tool' => TOOL_QUIZ,
'tool_id' => $exerciseId,
'tool_id_detail' => 0,
'action' => ((int) $_REQUEST['learnpath_id'] > 0) ? 'learnpath_id' : '',
'action_details' => ((int) $_REQUEST['learnpath_id'] > 0) ? (int) $_REQUEST['learnpath_id'] : '',
'current_id' => $current_question,
'info' => '',
];
Event::registerLog($logInfo);
// Error message
$error = '';
@ -721,7 +732,7 @@ if ($formSent && isset($_POST)) {
exit;
} else {
if ($debug) {
error_log('10. Redirecting to exercise_show.php');
error_log('10. Redirecting to exercise_result.php');
}
header("Location: exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
exit;

@ -1196,7 +1196,12 @@ class FillBlanks extends Question
$result = '';
$listStudentAnswerInfo = self::getAnswerInfo($answer, true);
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if (in_array($resultsDisabled, [
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
)
) {
$resultsDisabled = true;
if ($showTotalScoreAndUserChoices) {
$resultsDisabled = false;
@ -1258,15 +1263,19 @@ class FillBlanks extends Question
$showTotalScoreAndUserChoices = false
) {
$hideExpectedAnswer = false;
if ($feedbackType == 0 && $resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
$hideExpectedAnswer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hideExpectedAnswer = true;
if ($showTotalScoreAndUserChoices) {
$hideExpectedAnswer = false;
}
switch ($resultsDisabled) {
case RESULT_DISABLE_SHOW_SCORE_ONLY:
if ($feedbackType == 0) {
$hideExpectedAnswer = true;
}
break;
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$hideExpectedAnswer = true;
if ($showTotalScoreAndUserChoices) {
$hideExpectedAnswer = false;
}
break;
}
$style = 'feedback-green';

@ -61,7 +61,7 @@ class FreeAnswer extends Question
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'" >
<tr>
<th>'.get_lang("Answer").'</th>
<th>'.get_lang('Answer').'</th>
</tr>';
return $header;

@ -130,7 +130,7 @@ class HotSpotDelineation extends HotSpot
*/
public function createForm(&$form, $exercise)
{
parent::createForm($form);
parent::createForm($form, $exercise);
}
/**

@ -323,7 +323,7 @@ if ($submitAnswers || $buttonBack) {
// sets the total weighting of the question
$objQuestion->updateWeighting($questionWeighting);
$objQuestion->save($exerciseId);
$objQuestion->save($objExercise);
$editQuestion = $questionId;
unset($modifyAnswers);
@ -333,7 +333,7 @@ if ($submitAnswers || $buttonBack) {
}
}
if ($modifyAnswers) {
if (isset($modifyAnswers)) {
if ($debug > 0) {
echo str_repeat('&nbsp;', 0).'$modifyAnswers is set'."<br />\n";
}

@ -27,13 +27,14 @@ if ($debug) {
error_log("Call to hotspot_answers.as.php");
}
$trackExerciseInfo = $objExercise->get_stat_track_exercise_info_by_exe_id($exeId);
// Check if student has access to the hotspot answers
if (!api_is_allowed_to_edit(null, true)) {
if (empty($exeId)) {
api_not_allowed();
}
$trackExerciseInfo = $objExercise->get_stat_track_exercise_info_by_exe_id($exeId);
if (empty($trackExerciseInfo)) {
api_not_allowed();
}
@ -92,7 +93,13 @@ $data['courseCode'] = $_course['path'];
$data['hotspots'] = [];
$showTotalScoreAndUserChoicesInLastAttempt = true;
if ($objExercise->selectResultsDisabled() == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if (in_array(
$objExercise->selectResultsDisabled(), [
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
)
) {
$showOnlyScore = true;
$showResults = true;
if ($objExercise->attempts > 0) {
@ -119,11 +126,19 @@ if ($objExercise->selectResultsDisabled() == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_S
}
$hideExpectedAnswer = false;
if ($objExercise->selectFeedbackType() == 0 && $objExercise->selectResultsDisabled() == 2) {
if ($objExercise->selectFeedbackType() == 0 &&
$objExercise->selectResultsDisabled() == RESULT_DISABLE_SHOW_SCORE_ONLY
) {
$hideExpectedAnswer = true;
}
if ($objExercise->selectResultsDisabled() == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if (in_array(
$objExercise->selectResultsDisabled(), [
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
)
) {
$hideExpectedAnswer = $showTotalScoreAndUserChoicesInLastAttempt ? false : true;
}

@ -39,9 +39,20 @@ $learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? intval($_REQUEST['l
$learnpathItemViewId = isset($_REQUEST['learnpath_item_view_id']) ? intval($_REQUEST['learnpath_item_view_id']) : null;
$origin = api_get_origin();
$logInfo = [
'tool' => TOOL_QUIZ,
'tool_id' => $exercise_id,
'tool_id_detail' => 0,
'action' => isset($_REQUEST['learnpath_id']) ? 'learnpath_id' : '',
'action_details' => isset($_REQUEST['learnpath_id']) ? (int) $_REQUEST['learnpath_id'] : '',
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
$interbreadcrumb[] = [
"url" => "exercise.php?".api_get_cidreq(),
"name" => get_lang('Exercises'),
'url' => 'exercise.php?'.api_get_cidreq(),
'name' => get_lang('Exercises'),
];
$interbreadcrumb[] = ["url" => "#", "name" => $objExercise->selectTitle(true)];
@ -186,7 +197,13 @@ if ($current_browser == 'Internet Explorer') {
}
$blockShowAnswers = false;
if ($objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if (in_array(
$objExercise->results_disabled,
[
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
])
) {
if (count($attempts) < $objExercise->attempts) {
$blockShowAnswers = true;
}
@ -228,7 +245,7 @@ if (!empty($attempts)) {
),
'userIp' => $attempt_result['user_ip'],
];
$attempt_link .= "&nbsp;&nbsp;&nbsp;".$teacher_revised;
$attempt_link .= '&nbsp;&nbsp;&nbsp;'.$teacher_revised;
if (in_array(
$objExercise->results_disabled,
@ -237,6 +254,7 @@ if (!empty($attempts)) {
RESULT_DISABLE_SHOW_SCORE_ONLY,
RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
)) {
$row['result'] = $score;
@ -248,16 +266,25 @@ if (!empty($attempts)) {
RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS,
RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
) || (
$objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY &&
$objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_END
)
) {
if ($blockShowAnswers) {
if ($blockShowAnswers &&
$objExercise->results_disabled != RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK
) {
$attempt_link = '';
}
if ($blockShowAnswers == true &&
$objExercise->results_disabled == RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK
) {
if (isset($row['result'])) {
unset($row['result']);
}
}
$row['attempt_link'] = $attempt_link;
}
$my_attempt_array[] = $row;
@ -265,10 +292,23 @@ if (!empty($attempts)) {
}
$header_names = [];
$table = new HTML_Table(['class' => 'table table-hover']);
$table = new HTML_Table(['class' => 'table table-striped table-hover']);
// Hiding score and answer
switch ($objExercise->results_disabled) {
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
if ($blockShowAnswers) {
$header_names = [get_lang('Attempt'), get_lang('StartDate'), get_lang('IP'), get_lang('Details')];
} else {
$header_names = [
get_lang('Attempt'),
get_lang('StartDate'),
get_lang('IP'),
get_lang('Score'),
get_lang('Details'),
];
}
break;
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
if ($blockShowAnswers) {
$header_names = [get_lang('Attempt'), get_lang('StartDate'), get_lang('IP'), get_lang('Score')];

@ -230,13 +230,13 @@ abstract class Question
{
$showQuestionTitleHtml = api_get_configuration_value('save_titles_as_html');
$title = $showQuestionTitleHtml ? '' : '<h4>';
$title = $showQuestionTitleHtml ? '' : '<strong>';
$title .= $itemNumber.'. '.$this->selectTitle();
$title .= $showQuestionTitleHtml ? '' : '</h4>';
$title .= $showQuestionTitleHtml ? '' : '</strong>';
return Display::div(
$title,
['class' => 'title']
['class' => 'question_title']
);
}
@ -1944,7 +1944,7 @@ abstract class Question
}
$score_label = get_lang('Wrong');
$class = 'error';
if ($score['pass'] == true) {
if (isset($score['pass']) && $score['pass'] == true) {
$score_label = get_lang('Correct');
$class = 'success';
}
@ -1957,8 +1957,10 @@ abstract class Question
} else {
$score_label = get_lang('NotRevised');
$class = 'warning';
$weight = float_format($score['weight'], 1);
$score['result'] = " ? / ".$weight;
if (isset($score['weight'])) {
$weight = float_format($score['weight'], 1);
$score['result'] = ' ? / '.$weight;
}
$model = ExerciseLib::getCourseScoreModel();
if (!empty($model)) {
$score['result'] = ' ? ';
@ -1981,13 +1983,16 @@ abstract class Question
$header .= $this->show_media_content();
}
$scoreCurrent = [
'used' => $score['score'],
'missing' => $score['weight'],
'used' => isset($score['score']) ? $score['score'] : '',
'missing' => isset($score['weight']) ? $score['weight'] : '',
];
$header .= Display::page_subheader2($counterLabel.'. '.$this->question);
// dont display score for certainty degree questions
if ($this->type != MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
$header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent);
if (isset($score['result'])) {
$header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent);
}
}
if ($this->type != READING_COMPREHENSION) {

@ -10,8 +10,8 @@ use ChamiloSession as Session;
*/
require_once __DIR__.'/../inc/global.inc.php';
$id = isset($_REQUEST['id']) ? intval($_GET['id']) : null; //exe id
$show_headers = isset($_REQUEST['show_headers']) ? intval($_REQUEST['show_headers']) : null; //exe id
$id = isset($_REQUEST['id']) ? (int) $_GET['id'] : null; //exe id
$show_headers = isset($_REQUEST['show_headers']) ? (int) $_REQUEST['show_headers'] : null;
$origin = api_get_origin();
if ($origin == 'learnpath') {
@ -57,10 +57,10 @@ $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'annotation/
if ($show_headers) {
$interbreadcrumb[] = [
"url" => "exercise.php?".api_get_cidreq(),
"name" => get_lang('Exercises'),
'url' => "exercise.php?".api_get_cidreq(),
'name' => get_lang('Exercises'),
];
$interbreadcrumb[] = ["url" => "#", "name" => get_lang('Result')];
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Result')];
$this_section = SECTION_COURSES;
Display::display_header();
} else {
@ -72,7 +72,6 @@ if ($show_headers) {
$message = Session::read('attempt_remaining');
Session::erase('attempt_remaining');
ExerciseLib::displayQuestionListByAttempt(
$objExercise,
$id,

@ -334,7 +334,7 @@ class UniqueAnswer extends Question
//$list_destination = $form -> getSubmitValue('destination'.$i);
//$destination_str = $form -> getSubmitValue('destination'.$i);
$try = $scenario['try'.$i];
$try = !empty($scenario['try'.$i]);
$lp = $scenario['lp'.$i];
$destination = $scenario['destination'.$i];
$url = trim($scenario['url'.$i]);

@ -39,7 +39,7 @@ if (isset($_GET['details'])) {
//$interbreadcrumb[] = array ("url" => api_get_path(WEB_COURSE_PATH).$course_info['directory'], 'name' => $course_info['title']);
}
$interbreadcrumb[] = [
"url" => "../tracking/courseLog.php?cidReq=".$get_course_code.'&studentlist=true&id_session='.api_get_session_id(),
"url" => "../tracking/courseLog.php?cidReq=".$get_course_code.'&studentlist=true&id_session='.(empty($_SESSION['id_session']) ? '' : $_SESSION['id_session']),
"name" => get_lang("Tracking"),
];
} else {
@ -219,4 +219,4 @@ $info_user['name'] = api_get_person_name($info_user['firstname'], $info_user['la
</table>
</form>
<strong><?php echo get_lang('imprime_sommaire'); ?> </strong>
<a href="#" onclick="window.print()"><img align="absbottom" src="../img/printmgr.gif" border="0"></a>
<a href="#" onclick="window.print()"><img align="absbottom" src="../img/printmgr.gif" border="0"></a>

@ -161,6 +161,8 @@ $actions = [
$threadData = getThreadInfo($threadId, $cId);
$gradeThisThread = empty($_POST) && ($threadData['threadQualifyMax'] > 0 || $threadData['threadWeight'] > 0);
$form = new FormValidator(
'thread',
'post',
@ -195,7 +197,7 @@ if ((api_is_course_admin() || api_is_session_general_coach() || api_is_course_tu
$form->addElement('hidden', 'thread_qualify_gradebook', false);
}
$form->addElement('html', '<div id="options_field" style="display:none">');
$form->addElement('html', '<div id="options_field" style="'.($gradeThisThread ? '' : 'display:none;').'">');
$form->addElement('text', 'numeric_calification', get_lang('QualificationNumeric'));
$form->applyFilter('numeric_calification', 'html_filter');
$form->addElement('text', 'calification_notebook_title', get_lang('TitleColumnGradebook'));
@ -227,7 +229,7 @@ $form->addElement('html', '</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_FORUM_THREAD, $threadId);
if (!empty($threadData)) {
$defaults['thread_qualify_gradebook'] = ($threadData['threadQualifyMax'] > 0 && empty($_POST)) ? 1 : 0;
$defaults['thread_qualify_gradebook'] = $gradeThisThread;
$defaults['thread_title'] = prepare4display($threadData['threadTitle']);
$defaults['thread_sticky'] = strval(intval($threadData['threadSticky']));
$defaults['thread_peer_qualify'] = intval($threadData['threadPeerQualify']);

@ -614,6 +614,17 @@ function store_forumcategory($values, $courseInfo = [], $showMessage = true)
api_get_user_id()
);
$return_message = get_lang('ForumCategoryEdited');
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'update-forumcategory',
'action_details' => 'forumcategory',
'current_id' => $values['forum_category_id'],
'info' => $clean_cat_title,
];
Event::registerLog($logInfo);
} else {
$params = [
'c_id' => $course_id,
@ -645,6 +656,17 @@ function store_forumcategory($values, $courseInfo = [], $showMessage = true)
);
}
$return_message = get_lang('ForumCategoryAdded');
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'new-forumcategory',
'action_details' => 'forumcategory',
'current_id' => $last_id,
'info' => $clean_cat_title,
];
Event::registerLog($logInfo);
}
if ($showMessage) {
@ -839,6 +861,17 @@ function store_forum($values, $courseInfo = [], $returnId = false)
$return_message = get_lang('ForumEdited');
$forumId = $values['forum_id'];
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $values['forum_id'],
'tool_id_detail' => 0,
'action' => 'update-forum',
'action_details' => 'forum',
'current_id' => $values['forum_id'],
'info' => $values['forum_title'],
];
Event::registerLog($logInfo);
} else {
if ($image_moved) {
$new_file_name = isset($new_file_name) ? $new_file_name : '';
@ -887,6 +920,17 @@ function store_forum($values, $courseInfo = [], $returnId = false)
$group_id,
$courseInfo
);
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $forumId,
'tool_id_detail' => 0,
'action' => 'new-forum',
'action_details' => 'forum',
'current_id' => $forumId,
'info' => $values['forum_title'],
];
Event::registerLog($logInfo);
}
$return_message = get_lang('ForumAdded');
}
@ -2590,9 +2634,10 @@ function count_number_of_forums_in_category($cat_id)
{
$table_forums = Database::get_course_table(TABLE_FORUM);
$course_id = api_get_course_int_id();
$cat_id = (int) $cat_id;
$sql = "SELECT count(*) AS number_of_forums
FROM ".$table_forums."
WHERE c_id = $course_id AND forum_category='".Database::escape_string($cat_id)."'";
FROM $table_forums
WHERE c_id = $course_id AND forum_category = $cat_id";
$result = Database::query($sql);
$row = Database::fetch_array($result);
@ -2610,6 +2655,17 @@ function updateThread($values)
return '';
}
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $values['forum_id'],
'tool_id_detail' => $values['thread_id'],
'action' => 'edit-thread',
'action_details' => 'thread',
'current_id' => $values['thread_id'],
'info' => $values['thread_title'],
];
Event::registerLog($logInfo);
$threadTable = Database::get_course_table(TABLE_FORUM_THREAD);
$courseId = api_get_course_int_id();
$courseCode = api_get_course_id();
@ -2856,6 +2912,17 @@ function store_thread(
);
$visible = 1;
}
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $values['forum_id'],
'tool_id_detail' => $lastThread->getIid(),
'action' => 'new-thread',
'action_details' => '',
'current_id' => $lastThread->getIid(),
'info' => $clean_post_title,
];
Event::registerLog($logInfo);
}
// We now store the content in the table_post table.
@ -2886,6 +2953,17 @@ function store_thread(
$lastPostId = $lastPost->getIid();
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $values['forum_id'],
'tool_id_detail' => $lastThread->getIid(),
'action' => 'new-post',
'action_details' => '',
'current_id' => $lastPostId,
'info' => $clean_post_title,
];
Event::registerLog($logInfo);
if ($lastPostId) {
$lastPost->setPostId($lastPostId);
$em->merge($lastPost);
@ -3683,6 +3761,17 @@ function store_reply($current_forum, $values, $courseId = 0, $userId = 0)
$values
);
add_forum_attachment_file('', $new_post_id);
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $values['forum_id'],
'tool_id_detail' => $values['thread_id'],
'action' => 'new-post',
'action_details' => $values['action'],
'current_id' => $new_post_id,
'info' => $values['post_title'],
];
Event::registerLog($logInfo);
}
Session::erase('formelements');
@ -3870,6 +3959,17 @@ function show_edit_post_form(
*/
function store_edit_post($forumInfo, $values)
{
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $_GET['forum'],
'tool_id_detail' => $values['thread_id'],
'action' => 'edit-post',
'action_details' => 'post',
'current_id' => $values['post_id'],
'info' => $values['post_title'],
];
Event::registerLog($logInfo);
$threadTable = Database::get_course_table(TABLE_FORUM_THREAD);
$table_posts = Database::get_course_table(TABLE_FORUM_POST);
$course_id = api_get_course_int_id();
@ -4247,10 +4347,8 @@ function send_notification_mails($forumId, $thread_id, $reply_info)
* be new posts and the user might have indicated that (s)he wanted to be
* informed about the new posts by mail.
*
* @param string Content type (post, thread, forum, forum_category)
* @param int Item DB ID
* @param string $content
* @param int $id
* @param string $content Content type (post, thread, forum, forum_category)
* @param int $id Item DB ID of the corresponding content type
*
* @return string language variable
*
@ -4267,13 +4365,14 @@ function handle_mail_cue($content, $id)
$table_users = Database::get_main_table(TABLE_MAIN_USER);
$course_id = api_get_course_int_id();
$id = (int) $id;
/* If the post is made visible we only have to send mails to the people
who indicated that they wanted to be informed for that thread.*/
if ($content == 'post') {
// Getting the information about the post (need the thread_id).
$post_info = get_post_information($id);
$thread_id = intval($post_info['thread_id']);
$thread_id = (int) $post_info['thread_id'];
// Sending the mail to all the users that wanted to be informed for replies on this thread.
$sql = "SELECT users.firstname, users.lastname, users.user_id, users.email
@ -4281,11 +4380,11 @@ function handle_mail_cue($content, $id)
WHERE
posts.c_id = $course_id AND
mailcue.c_id = $course_id AND
posts.thread_id='$thread_id'
AND posts.post_notification='1'
AND mailcue.thread_id='$thread_id'
AND users.user_id=posts.poster_id
AND users.active=1
posts.thread_id = $thread_id AND
posts.post_notification = '1' AND
mailcue.thread_id = $thread_id AND
users.user_id = posts.poster_id AND
users.active = 1
GROUP BY users.email";
$result = Database::query($sql);
@ -4299,11 +4398,11 @@ function handle_mail_cue($content, $id)
WHERE
posts.c_id = $course_id AND
mailcue.c_id = $course_id AND
posts.thread_id = ".intval($id)."
AND posts.post_notification='1'
AND mailcue.thread_id = ".intval($id)."
AND users.user_id=posts.poster_id
AND users.active=1
posts.thread_id = $id AND
posts.post_notification = '1' AND
mailcue.thread_id = $id AND
users.user_id = posts.poster_id
users.active = 1
GROUP BY users.email";
$result = Database::query($sql);
while ($row = Database::fetch_array($result)) {
@ -4312,18 +4411,18 @@ function handle_mail_cue($content, $id)
// Deleting the relevant entries from the mailcue.
$sql = "DELETE FROM $table_mailcue
WHERE c_id = $course_id AND thread_id='".Database::escape_string($id)."'";
WHERE c_id = $course_id AND thread_id = $id";
Database::query($sql);
} elseif ($content == 'forum') {
$sql = "SELECT thread_id FROM $table_threads
WHERE c_id = $course_id AND forum_id='".Database::escape_string($id)."'";
WHERE c_id = $course_id AND forum_id = $id";
$result = Database::query($sql);
while ($row = Database::fetch_array($result)) {
handle_mail_cue('thread', $row['thread_id']);
}
} elseif ($content == 'forum_category') {
$sql = "SELECT forum_id FROM $table_forums
WHERE c_id = $course_id AND forum_category ='".Database::escape_string($id)."'";
WHERE c_id = $course_id AND forum_category = $id";
$result = Database::query($sql);
while ($row = Database::fetch_array($result)) {
handle_mail_cue('forum', $row['forum_id']);

@ -121,6 +121,18 @@ $whatsnew_post_info = Session::read('whatsnew_post_info');
/* TRACKING */
Event::event_access_tool(TOOL_FORUM);
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => !empty($actions) ? $actions : 'list-category',
'action_details' => $_GET['content'],
'current_id' => !empty($actions) ? (int) $_GET['id'] : 0,
'info' => '',
];
Event::registerLog($logInfo);
/*
RETRIEVING ALL THE FORUM CATEGORIES AND FORUMS
note: we do this here just after het handling of the actions to be

@ -45,6 +45,16 @@ $origin = api_get_origin();
$current_forum = get_forum_information($_GET['forum']);
$current_forum_category = get_forumcategory_information($current_forum['forum_category']);
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => (int) $_GET['forum'],
'tool_id_detail' => 0,
'action' => 'add-thread',
'action_details' => '',
'current_id' => 0,
];
Event::registerLog($logInfo);
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
'url' => Category::getUrl(),

@ -155,6 +155,16 @@ $my_action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : ''
$my_post = isset($_GET['post']) ? Security::remove_XSS($_GET['post']) : '';
$my_elements = isset($_SESSION['formelements']) ? $_SESSION['formelements'] : '';
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $forumId,
'tool_id_detail' => $threadId,
'action' => !empty($my_action) ? $my_action : 'reply',
'action_details' => '',
'current_id' => $my_post,
];
Event::registerLog($logInfo);
$form = show_add_post_form(
$current_forum,
$forum_setting,

@ -103,6 +103,16 @@ if (!empty($groupId)) {
$my_search = isset($_GET['search']) ? $_GET['search'] : '';
$my_action = isset($_GET['action']) ? $_GET['action'] : '';
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $my_forum,
'tool_id_detail' => 0,
'action' => !empty($my_action) ? $my_action : 'list-threads',
'action_details' => $_GET['content'],
'current_id' => !empty($my_action) ? (int) $_GET['id'] : 0,
];
Event::registerLog($logInfo);
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
'url' => Category::getUrl(),

@ -122,9 +122,17 @@ if (api_is_allowed_to_edit(false, true)) {
$html .= search_link();
$html .= '</div>';
/* ACTIONS */
echo $html;
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'info' => $_GET['content'],
];
Event::registerLog($logInfo);
if (api_is_allowed_to_edit(false, true)) {
handle_forum_and_forumcategories();
}

@ -125,6 +125,17 @@ if (!api_is_allowed_to_edit(false, true) &&
/* Actions */
$my_action = isset($_GET['action']) ? $_GET['action'] : '';
$logInfo = [
'tool' => TOOL_FORUM,
'tool_id' => $_GET['forum'],
'tool_id_detail' => $_GET['thread'],
'action' => !empty($my_action) ? $my_action : 'view-thread',
'action_details' => $_GET['content'],
'current_id' => !empty($my_action) ? (int) $_GET['id'] : 0,
];
Event::registerLog($logInfo);
if ($my_action == 'delete' &&
isset($_GET['content']) &&
isset($_GET['id']) &&

@ -89,10 +89,33 @@ if ($form->validate()) {
}
$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(),
'current_id' => $cat->get_id(),
'info' => '',
];
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,
'current_id' => $current_id,
'info' => '',
];
Event::registerLog($logInfo);
if (!$_in_course) {
$interbreadcrumb[] = [
'url' => Category::getUrl().'selectcat='.$get_select_cat,

@ -67,6 +67,18 @@ if ($form->validate()) {
}
$eval->set_visible($visible);
$eval->add();
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'new-eval',
'action_details' => 'selectcat='.$eval->get_category_id(),
'current_id' => $eval->get_id(),
'info' => '',
];
Event::registerLog($logInfo);
if ($eval->get_course_code() == null) {
if ($values['adduser'] == 1) {
//Disabling code when course code is null see issue #2705
@ -88,6 +100,17 @@ if ($form->validate()) {
}
}
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'add-eval',
'action_details' => 'selectcat='.$select_cat,
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
$interbreadcrumb[] = [
'url' => Category::getUrl().'selectcat='.$select_cat,
'name' => get_lang('Gradebook'), ]

@ -131,6 +131,18 @@ if (isset($typeSelected) && $typeSelected != '0') {
}
$link->add();
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'new-link',
'action_details' => 'selectcat='.$selectCat,
'current_id' => $link->get_id(),
'info' => '',
];
Event::registerLog($logInfo);
$addvalue_result = !empty($addvalues['addresult']) ? $addvalues['addresult'] : [];
if ($addvalue_result == 1) {
header('Location: gradebook_add_result.php?selecteval='.$link->get_ref_id().'&'.api_get_cidreq());
@ -142,6 +154,24 @@ if (isset($typeSelected) && $typeSelected != '0') {
}
}
$action_details = '';
$current_id = 0;
if (isset($_GET['selectcat'])) {
$action_details = 'selectcat';
$current_id = (int) $_GET['selectcat'];
}
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'add-link',
'action_details' => 'selectcat='.$selectCat,
'current_id' => $current_id,
'info' => '',
];
Event::registerLog($logInfo);
$interbreadcrumb[] = [
'url' => Category::getUrl().'selectcat='.$selectCat,
'name' => get_lang('Gradebook'),

@ -30,10 +30,6 @@ $userList = CourseManager::get_user_list_from_course_code(
switch ($action) {
case 'export_all':
$params = [];
$pdf = new PDF('A4', 'P', $params);
$pdfList = [];
$cats = Category::load($cat_id, null, null, null, null, null, false);
$studentList = CourseManager::get_user_list_from_course_code(
api_get_course_id(),
@ -44,7 +40,6 @@ switch ($action) {
);
$tpl = new Template('', false, false, false);
$courseInfo = api_get_course_info();
$params = [
'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['name']),
@ -56,22 +51,22 @@ switch ($action) {
'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);
$htmlList = [];
foreach ($userList as $index => $value) {
$pdfList[] = GradebookUtils::generateTable(
$htmlList[] = GradebookUtils::generateTable(
$value['user_id'],
$cats,
false,
true,
true,
$studentList,
$pdf
);
}
if (!empty($pdfList)) {
if (!empty($htmlList)) {
// Print certificates (without the common header/footer/watermark
// stuff) and return as one multiple-pages PDF
/*$address = api_get_setting('institution_address');
@ -80,7 +75,7 @@ switch ($action) {
$pdf->custom_header = array('html' => "<h5 align='right'>$address <br />$phone</h5>");*/
// stuff) and return as one multiple-pages PDF
$pdf->html_to_pdf(
$pdfList,
$htmlList,
null,
null,
false,

@ -16,12 +16,28 @@ api_protect_course_script(true);
api_block_anonymous_users();
GradebookUtils::block_students();
$my_selectcat = isset($_GET['selectcat']) ? intval($_GET['selectcat']) : 0;
$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,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'edit-weight',
'action_details' => $action_details,
'current_id' => $my_selectcat,
'info' => '',
];
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);

@ -10,7 +10,6 @@ require_once __DIR__.'/../inc/global.inc.php';
api_block_anonymous_users();
GradebookUtils::block_students();
$edit_cat = isset($_REQUEST['editcat']) ? intval($_REQUEST['editcat']) : '';
$catedit = Category::load($edit_cat);
@ -84,7 +83,26 @@ if ($form->validate()) {
header('Location: '.Category::getUrl().'editcat=&selectcat='.$cat->get_parent_id());
exit;
}
$selectcat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : '';
$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,
'current_id' => $current_id,
'info' => '',
];
Event::registerLog($logInfo);
$interbreadcrumb[] = [
'url' => Category::getUrl().'selectcat='.$selectcat,
'name' => get_lang('Gradebook'),

@ -44,6 +44,18 @@ if ($form->validate()) {
}
$eval->set_visible($visible);
$eval->save();
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'edit-eval',
'action_details' => '',
'current_id' => $eval->get_category_id(),
'info' => '',
];
Event::registerLog($logInfo);
header('Location: '.Category::getUrl().'editeval=&selectcat='.$eval->get_category_id());
exit;
}

@ -105,6 +105,17 @@ if ($form->validate()) {
'type' => LINK_STUDENTPUBLICATION,
]);
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'edit-link',
'action_details' => '',
'current_id' => $_GET['editlink'],
'info' => '',
];
Event::registerLog($logInfo);
header('Location: '.Category::getUrl().'linkedited=&selectcat='.$link->get_category_id());
exit;
}

@ -66,6 +66,64 @@ $(document).ready(function() {
});
</script>';
$list_actions = [];
$list_values = [];
if (isset($_GET['movecat'])) {
$list_actions[] = 'movecat';
$list_values[] = $_GET['movecat'];
}
if (isset($_GET['moveeval'])) {
$list_actions[] = 'moveeval';
$list_values[] = $_GET['moveeval'];
}
if (isset($_GET['movelink'])) {
$list_actions[] = 'movelink';
$list_values[] = $_GET['movelink'];
}
if (isset($_GET['visiblecat'])) {
$list_actions[] = 'visiblecat';
$list_values[] = $_GET['visiblecat'];
}
if (isset($_GET['deletecat'])) {
$list_actions[] = 'deletecat';
$list_values[] = $_GET['deletecat'];
}
if (isset($_GET['visibleeval'])) {
$list_actions[] = 'visibleeval';
$list_values[] = $_GET['visibleeval'];
}
if (isset($_GET['lockedeval'])) {
$list_actions[] = 'lockedeval';
$list_values[] = $_GET['lockedeval'];
}
if (isset($_GET['deleteeval'])) {
$list_actions[] = 'deleteeval';
$list_values[] = $_GET['deleteeval'];
}
if (isset($_GET['visiblelink'])) {
$list_actions[] = 'visiblelink';
$list_values[] = $_GET['visiblelink'];
}
if (isset($_GET['deletelink'])) {
$list_actions[] = 'deletelink';
$list_values[] = $_GET['deletelink'];
}
if (isset($_GET['action'])) {
$list_actions[] = $_GET['action'];
}
$my_actions = implode(';', $list_actions);
$my_actions_values = implode(';', $list_values);
$logInfo = [
'tool' => TOOL_GRADEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $my_actions,
'action_details' => $my_actions_values,
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
$tbl_forum_thread = Database::get_course_table(TABLE_FORUM_THREAD);
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
$tbl_grade_links = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);

@ -445,8 +445,8 @@ class Category implements GradebookItem
return $cats;
}
$tbl_grade_categories = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = 'SELECT * FROM '.$tbl_grade_categories;
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = 'SELECT * FROM '.$table;
$paramcount = 0;
if (isset($id)) {
$sql .= ' WHERE id = '.intval($id);

@ -113,7 +113,7 @@ class Evaluation implements GradebookItem
*/
public function setSessionId($sessionId)
{
$this->sessionId = intval($sessionId);
$this->sessionId = (int) $sessionId;
}
public function get_date()
@ -153,7 +153,7 @@ class Evaluation implements GradebookItem
public function set_id($id)
{
$this->id = $id;
$this->id = (int) $id;
}
public function set_name($name)

@ -322,7 +322,7 @@ class DisplayGradebook
if (!empty($score)) {
$divide = $score[1] == 0 ? 1 : $score[1];
$item_value = $score[0] / $divide * $item->get_weight();
$item_value_total += $scoredisplay->format_score($item_value);
$item_value_total += $item_value;
}
}

@ -12,6 +12,17 @@ $cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
$logInfo = [
'tool' => 'MyCertificates',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => '',
'action_details' => '',
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
if (api_is_anonymous()) {
api_not_allowed(true);
}

@ -79,6 +79,7 @@ if (isset($_GET['id'])) {
'announcements_state' => GroupManager::TOOL_PRIVATE,
'forum_state' => GroupManager::TOOL_PRIVATE,
'max_student' => 0,
'document_access' => 0,
];
}

@ -18,6 +18,15 @@ if ($type == 'course') {
api_protect_course_script(true);
}
$logInfo = [
'tool' => TOOL_CALENDAR_EVENT,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'info' => '',
];
Event::registerLog($logInfo);
$agenda = new Agenda($type);
// get filtered type
$type = $agenda->getType();

@ -32,7 +32,6 @@ switch ($action) {
case 'get_course_image':
$courseId = ChamiloApi::getCourseIdByDirectory($_REQUEST['code']);
$courseInfo = api_get_course_info_by_id($courseId);
$image = isset($_REQUEST['image']) && in_array($_REQUEST['image'], ['course_image_large_source', 'course_image_source']) ? $_REQUEST['image'] : '';
if ($courseInfo && $image) {
DocumentManager::file_send_for_download($courseInfo[$image]);
@ -366,6 +365,14 @@ switch ($action) {
'sid' => api_get_session_id(),
];
$logInfo = [
'tool' => 'close-window',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'exit',
];
Event::registerLog($logInfo);
$result = (int) Event::courseLogout($logoutInfo);
echo $result;
break;

@ -18,6 +18,18 @@ $json = ['status' => false];
$courseChatUtils = new CourseChatUtils($courseId, $userId, $sessionId, $groupId);
switch ($_REQUEST['action']) {
case 'chat_logout':
$logInfo = [
'tool' => TOOL_CHAT,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'exit',
'action_details' => 'exit-chat',
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
break;
case 'track':
$courseChatUtils->keepUserAsConnected();
$courseChatUtils->disconnectInactiveUsers();

@ -586,7 +586,6 @@ switch ($action) {
$courseInfo = api_get_course_info_by_id($courseId);
$courseInfo['id_session'] = $sessionId;
$courseInfo['status'] = $status;
$id = 'notification_'.$courseId.'_'.$sessionId.'_'.$status;
$notificationId = Session::read($id);

@ -198,10 +198,14 @@ switch ($action) {
}
break;
case 'list_wall_message':
$start = isset($_REQUEST['start']) ? intval($_REQUEST['start']) - 1 : 0;
$length = isset($_REQUEST['length']) ? intval($_REQUEST['length']) : 10;
$userId = isset($_REQUEST['u']) ? intval($_REQUEST['u']) : api_get_user_id();
if (api_is_anonymous()) {
break;
}
$start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] - 1 : 0;
$length = isset($_REQUEST['length']) ? (int) $_REQUEST['length'] : 10;
$userId = isset($_REQUEST['u']) ? (int) $_REQUEST['u'] : api_get_user_id();
$friendId = $userId;
$array = SocialManager::getWallMessagesPostHTML($userId, $friendId, null, $length, $start);
if (!empty($array)) {
ksort($array);

@ -113,7 +113,7 @@ class TicketManager
public static function getCategory($id)
{
$table = Database::get_main_table(TABLE_TICKET_CATEGORY);
$id = intval($id);
$id = (int) $id;
$sql = "SELECT id, name, description, total_tickets
FROM $table WHERE id = $id";
@ -146,7 +146,7 @@ class TicketManager
public static function updateCategory($id, $params)
{
$table = Database::get_main_table(TABLE_TICKET_CATEGORY);
$id = intval($id);
$id = (int) $id;
Database::update($table, $params, ['id = ?' => $id]);
}
@ -314,10 +314,10 @@ class TicketManager
$currentUserId = api_get_user_id();
$currentUserInfo = api_get_user_info();
$now = api_get_utc_datetime();
$course_id = intval($course_id);
$category_id = intval($category_id);
$project_id = intval($project_id);
$priority = empty($priority) ? self::PRIORITY_NORMAL : $priority;
$course_id = (int) $course_id;
$category_id = (int) $category_id;
$project_id = (int) $project_id;
$priority = empty($priority) ? self::PRIORITY_NORMAL : (int) $priority;
if ($status === '') {
$status = self::STATUS_NEW;
@ -457,11 +457,11 @@ class TicketManager
</tr>
<tr>
<td width="100px"><b>'.get_lang('Title').'</b></td>
<td width="400px">'.$subject.'</td>
<td width="400px">'.Security::remove_XSS($subject).'</td>
</tr>
<tr>
<td width="100px"><b>'.get_lang('Description').'</b></td>
<td width="400px">'.$content.'</td>
<td width="400px">'.Security::remove_XSS($content).'</td>
</tr>
</table>';
@ -655,7 +655,7 @@ class TicketManager
'ticket_id' => $ticketId,
'subject' => $subject,
'message' => $content,
'ip_address' => $_SERVER['REMOTE_ADDR'],
'ip_address' => api_get_real_ip(),
'sys_insert_user_id' => $userId,
'sys_insert_datetime' => $now,
'sys_lastedit_user_id' => $userId,
@ -667,12 +667,12 @@ class TicketManager
// update_total_message
$sql = "UPDATE $table_support_tickets
SET
sys_lastedit_user_id ='$userId',
sys_lastedit_user_id = $userId,
sys_lastedit_datetime ='$now',
total_messages = (
SELECT COUNT(*) as total_messages
FROM $table_support_messages
WHERE ticket_id ='$ticketId'
WHERE ticket_id = $ticketId
)
WHERE id = $ticketId ";
Database::query($sql);
@ -1409,9 +1409,9 @@ class TicketManager
$now = api_get_utc_datetime();
$table = Database::get_main_table(TABLE_TICKET_TICKET);
$newParams = [
'priority_id' => isset($params['priority_id']) ? $params['priority_id'] : '',
'status_id' => isset($params['status_id']) ? $params['status_id'] : '',
'sys_lastedit_user_id' => $userId,
'priority_id' => isset($params['priority_id']) ? (int) $params['priority_id'] : '',
'status_id' => isset($params['status_id']) ? (int) $params['status_id'] : '',
'sys_lastedit_user_id' => (int) $userId,
'sys_lastedit_datetime' => $now,
];
Database::update($table, $newParams, ['id = ? ' => $ticketId]);
@ -1503,14 +1503,14 @@ class TicketManager
$table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
$now = api_get_utc_datetime();
$ticketId = intval($ticketId);
$userId = intval($userId);
$ticketId = (int) $ticketId;
$userId = (int) $userId;
$sql = "UPDATE $table_support_tickets SET
priority_id = '".self::PRIORITY_HIGH."',
sys_lastedit_user_id ='$userId',
sys_lastedit_user_id = $userId,
sys_lastedit_datetime ='$now'
WHERE id = '$ticketId'";
WHERE id = $ticketId";
Database::query($sql);
}

@ -112,7 +112,7 @@ class Agenda
$this->events = [];
$agendaColors = array_merge(
[
'platform' => '#EB4E36', //red
'platform' => 'red', //red
'course' => '#43D29E', //green
'group' => '#A0522D', //siena
'session' => '#00496D', // kind of green
@ -3002,7 +3002,7 @@ class Agenda
'',
'',
[],
FormValidator::LAYOUT_BOX_SEARCH
FormValidator::LAYOUT_INLINE
);
$attributes = [
'multiple' => false,
@ -3031,7 +3031,7 @@ class Agenda
api_get_self().'?type=personal&',
'',
[],
FormValidator::LAYOUT_BOX_SEARCH
FormValidator::LAYOUT_INLINE
);
if (api_is_drh()) {

@ -3370,6 +3370,7 @@ function api_display_tool_view_option()
$output_string .= '<a class="btn btn-default btn-sm" href="'.$sourceurl.'&isStudentView=true" target="_self">'.
Display::returnFontAwesomeIcon('eye').' '.get_lang('SwitchToStudentView').'</a>';
}
$output_string = Security::remove_XSS($output_string);
$html = Display::tag('div', $output_string, ['class' => 'view-options']);
return $html;
@ -5036,7 +5037,7 @@ function api_max_sort_value($user_course_category, $user_id)
*
* @return string the formated time
*/
function api_time_to_hms($seconds)
function api_time_to_hms($seconds, $space = ':')
{
// $seconds = -1 means that we have wrong data in the db.
if ($seconds == -1) {
@ -5058,6 +5059,10 @@ function api_time_to_hms($seconds)
// How many seconds
$sec = floor($seconds - ($hours * 3600) - ($min * 60));
if ($hours < 10) {
$hours = "0$hours";
}
if ($sec < 10) {
$sec = "0$sec";
}
@ -5066,7 +5071,7 @@ function api_time_to_hms($seconds)
$min = "0$min";
}
return "$hours:$min:$sec";
return $hours.$space.$min.$space.$sec;
}
/* FILE SYSTEM RELATED FUNCTIONS */
@ -6156,7 +6161,6 @@ function api_is_course_visible_for_user($userid = null, $cid = null)
* @param string the tool of the element
* @param int the element id in database
* @param int the session_id to compare with element session id
* @param string $tool
*
* @return bool true if the element is in the session, false else
*/
@ -6166,6 +6170,12 @@ function api_is_element_in_the_session($tool, $element_id, $session_id = null)
$session_id = api_get_session_id();
}
$element_id = (int) $element_id;
if (empty($element_id)) {
return false;
}
// Get information to build query depending of the tool.
switch ($tool) {
case TOOL_SURVEY:
@ -6190,7 +6200,7 @@ function api_is_element_in_the_session($tool, $element_id, $session_id = null)
$course_id = api_get_course_int_id();
$sql = "SELECT session_id FROM $table_tool
WHERE c_id = $course_id AND $key_field = ".intval($element_id);
WHERE c_id = $course_id AND $key_field = ".$element_id;
$rs = Database::query($sql);
if ($element_session_id = Database::result($rs, 0, 0)) {
if ($element_session_id == intval($session_id)) {

@ -52,7 +52,9 @@ class Attendance
$sql = "SELECT COUNT(att.id) AS total_number_of_items
FROM $tbl_attendance att
WHERE c_id = $course_id $condition_session ";
if ($active == 1 || $active == 0) {
$active = (int) $active;
if ($active === 1 || $active === 0) {
$sql .= "AND att.active = $active";
}
$res = Database::query($sql);
@ -72,12 +74,12 @@ class Attendance
public function get_attendances_list($course_id = 0, $session_id = 0)
{
$table = Database::get_course_table(TABLE_ATTENDANCE);
$course_id = intval($course_id);
$course_id = (int) $course_id;
if (empty($course_id)) {
$course_id = api_get_course_int_id();
}
$session_id = !empty($session_id) ? intval($session_id) : api_get_session_id();
$session_id = !empty($session_id) ? (int) $session_id : api_get_session_id();
$condition_session = api_get_session_condition($session_id);
// Get attendance data
@ -286,7 +288,7 @@ class Attendance
public function get_attendance_by_id($attendanceId)
{
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$course_id = api_get_course_int_id();
$attendance_data = [];
$sql = "SELECT * FROM $tbl_attendance
@ -394,7 +396,7 @@ class Attendance
$session_id = api_get_session_id();
$user_id = api_get_user_id();
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$course_code = $_course['code'];
$course_id = $_course['real_id'];
$title_gradebook = $this->attendance_qualify_title;
@ -470,7 +472,7 @@ class Attendance
$course_id = $_course['real_id'];
if (is_array($attendanceId)) {
foreach ($attendanceId as $id) {
$id = intval($id);
$id = (int) $id;
$sql = "UPDATE $tbl_attendance SET active = 1
WHERE c_id = $course_id AND id = '$id'";
$result = Database::query($sql);
@ -487,7 +489,7 @@ class Attendance
}
}
} else {
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$sql = "UPDATE $tbl_attendance SET active = 1
WHERE c_id = $course_id AND id = '$attendanceId'";
$result = Database::query($sql);
@ -575,7 +577,7 @@ class Attendance
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
$user_id = api_get_user_id();
$course_id = $_course['real_id'];
$status = intval($status);
$status = (int) $status;
$action = 'visible';
if ($status == 0) {
@ -584,7 +586,7 @@ class Attendance
if (is_array($attendanceId)) {
foreach ($attendanceId as $id) {
$id = intval($id);
$id = (int) $id;
$sql = "UPDATE $tbl_attendance SET active = $status
WHERE c_id = $course_id AND id = '$id'";
$result = Database::query($sql);
@ -601,7 +603,7 @@ class Attendance
}
}
} else {
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$sql = "UPDATE $tbl_attendance SET active = $status
WHERE c_id = $course_id AND id = '$attendanceId'";
$result = Database::query($sql);
@ -633,8 +635,8 @@ class Attendance
{
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
$course_id = api_get_course_int_id();
$attendanceId = intval($attendanceId);
$locked = ($lock) ? 1 : 0;
$attendanceId = (int) $attendanceId;
$locked = $lock ? 1 : 0;
$upd = "UPDATE $tbl_attendance SET locked = $locked
WHERE c_id = $course_id AND id = $attendanceId";
$result = Database::query($upd);
@ -776,8 +778,8 @@ class Attendance
$tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
$tbl_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
$calendar_id = intval($calendar_id);
$attendanceId = intval($attendanceId);
$calendar_id = (int) $calendar_id;
$attendanceId = (int) $attendanceId;
$users = $this->get_users_rel_course();
$course_id = api_get_course_int_id();
@ -794,7 +796,7 @@ class Attendance
// save users present in class
foreach ($users_present as $user_present) {
$uid = intval($user_present);
$uid = (int) $user_present;
// check if user already was registered with the $calendar_id
$sql = "SELECT user_id FROM $tbl_attendance_sheet
WHERE c_id = $course_id AND user_id='$uid' AND attendance_calendar_id = '$calendar_id'";
@ -901,6 +903,7 @@ class Attendance
// get count of presences by users inside current attendance and save like results
if (count($user_ids) > 0) {
foreach ($user_ids as $uid) {
$uid = (int) $uid;
$count_presences = 0;
if (count($calendar_ids) > 0) {
$sql = "SELECT count(presence) as count_presences
@ -1239,6 +1242,7 @@ class Attendance
$user_ids = array_keys($users);
if (count($calendar_ids) > 0 && count($user_ids) > 0) {
foreach ($user_ids as $uid) {
$uid = (int) $uid;
$sql = "SELECT * FROM $tbl_attendance_sheet
WHERE
c_id = $course_id AND
@ -1255,7 +1259,7 @@ class Attendance
}
} else {
// Get attendance for current user
$user_id = intval($user_id);
$user_id = (int) $user_id;
if (count($calendar_ids) > 0) {
$sql = "SELECT cal.date_time, att.presence
FROM $tbl_attendance_sheet att
@ -1290,7 +1294,7 @@ class Attendance
public function get_next_attendance_calendar_id($attendanceId)
{
$table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$course_id = api_get_course_int_id();
$sql = "SELECT id FROM $table
@ -1321,7 +1325,7 @@ class Attendance
{
$table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
$course_id = api_get_course_int_id();
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$sql = "SELECT id, date_time FROM $table
WHERE
c_id = $course_id AND
@ -1358,6 +1362,7 @@ class Attendance
$attendanceId = intval($attendanceId);
$groupId = (int) $groupId;
$course_id = api_get_course_int_id();
if (empty($groupId)) {
$sql = "SELECT score FROM $tbl_attendance_result
WHERE
@ -1647,13 +1652,13 @@ class Attendance
*/
public static function is_all_attendance_calendar_done($attendanceId)
{
$attendanceId = intval($attendanceId);
$attendanceId = (int) $attendanceId;
$done_calendar = self::get_done_attendance_calendar($attendanceId);
$count_dates_in_calendar = self::get_count_dates_inside_attendance_calendar($attendanceId);
$number_of_dates = self::get_number_of_attendance_calendar($attendanceId);
$result = false;
if ($number_of_dates && (intval($count_dates_in_calendar) == intval($done_calendar))) {
if ($number_of_dates && intval($count_dates_in_calendar) == intval($done_calendar)) {
$result = true;
}
@ -1739,7 +1744,6 @@ class Attendance
}
$table = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR_REL_GROUP);
foreach ($groupList as $groupId) {
if (empty($groupId)) {
continue;
@ -1777,7 +1781,8 @@ class Attendance
return Database::select(
'*',
$table,
['where' => [
[
'where' => [
'calendar_id = ? AND c_id = ?' => [$calendarId, $courseId],
],
]
@ -1798,7 +1803,8 @@ class Attendance
return Database::select(
'*',
$table,
['where' => [
[
'where' => [
'calendar_id = ? AND c_id = ? AND group_id = ?' => [$calendarId, $courseId, $groupId],
],
]
@ -1935,6 +1941,8 @@ class Attendance
$tbl_attendance_sheet = Database::get_course_table(TABLE_ATTENDANCE_SHEET);
$attendanceId = intval($attendanceId);
$calendar_id = (int) $calendar_id;
// get all registered users inside current course
$users = $this->get_users_rel_course();
$user_ids = array_keys($users);
@ -1961,11 +1969,11 @@ class Attendance
} else {
// delete just one row from attendance sheet by the calendar id
$sql = "DELETE FROM $tbl_attendance_sheet
WHERE c_id = $course_id AND attendance_calendar_id = '".intval($calendar_id)."'";
WHERE c_id = $course_id AND attendance_calendar_id = '".$calendar_id."'";
Database::query($sql);
// delete data from attendance calendar
$sql = "DELETE FROM $tbl_attendance_calendar
WHERE c_id = $course_id AND id = '".intval($calendar_id)."'";
WHERE c_id = $course_id AND id = '".$calendar_id."'";
Database::query($sql);
$this->deleteAttendanceCalendarGroup($calendar_id, $course_id);
@ -1978,10 +1986,9 @@ class Attendance
return $affected_rows;
}
/** Setters for fields of attendances tables */
public function set_session_id($session_id)
public function set_session_id($sessionId)
{
$this->session_id = $session_id;
$this->session_id = $sessionId;
}
public function set_course_id($course_id)

@ -47,18 +47,23 @@ function getCustomTabs()
* Return the active logo of the portal, based on a series of settings.
*
* @param string $theme The name of the theme folder from web/css/themes/
* @param bool $responsive add class img-responsive
*
* @return string HTML string with logo as an HTML element
*/
function return_logo($theme = '')
function return_logo($theme = '', $responsive = true)
{
$siteName = api_get_setting('siteName');
$class = 'img-responsive';
if (!$responsive) {
$class = '';
}
return ChamiloApi::getPlatformLogo(
$theme,
[
'title' => $siteName,
'class' => 'img-responsive',
'class' => $class,
'id' => 'header-logo',
]
);

@ -2800,7 +2800,7 @@ class Blog
}
}
$html .= '<table id="smallcalendar" class="table">
$html .= '<table id="smallcalendar" class="table table-responsive">
<tr id="title">
<th width="10%"><a href="'.$backwardsURL.'">&laquo;</a></th>
<th align="center" width="80%" colspan="5" class="month">'.$monthName.' '.$year.'</th>

@ -4094,7 +4094,6 @@ class CourseManager
$params['image'] = $image;
$params['title'] = $course_info['title'];
$params['title_cut'] = $params['title'];
$params['category'] = $course_info['categoryName'];
$params['category_code'] = $course_info['categoryCode'];
$params['category_id'] = $course_info['categoryId'];
@ -6718,7 +6717,7 @@ class CourseManager
$title = $course['title'];
$url = api_get_path(WEB_CODE_PATH).'inc/ajax/course_home.ajax.php?a=show_course_information&code='.$course['code'];
$html = Display::url(
Display::returnFontAwesomeIcon('info-circle'),
Display::returnFontAwesomeIcon('info-circle', 'lg'),
$url,
[
'class' => 'ajax btn btn-light btn-sm',

@ -1339,14 +1339,13 @@ class CourseHome
}
$blocks = self::getUserBlocks();
$html = '';
if (!empty($blocks)) {
$style_id = 'toolshortcuts_vertical';
$styleId = 'toolshortcuts_vertical';
if ($orientation == SHORTCUTS_HORIZONTAL) {
$style_id = 'toolshortcuts_horizontal';
$styleId = 'toolshortcuts_horizontal';
}
$html .= '<div id="'.$style_id.'">';
$html .= '<div id="'.$styleId.'">';
$html .= Display::url(
Display::return_icon('home.png', get_lang('CourseHomepageLink'), '', ICON_SIZE_MEDIUM),
@ -1573,6 +1572,7 @@ class CourseHome
{
$blocks = [];
$my_list = self::get_tools_category(TOOL_AUTHORING);
$blocks[] = [
'title' => get_lang('Authoring'),
'class' => 'course-tools-author',

@ -73,7 +73,7 @@ class DocumentManager
{
// All MIME types in an array (from 1.6, this is the authorative source)
// Please, keep this alphabetical if you add something to this list!
$mime_types = [
$mimeTypes = [
'ai' => 'application/postscript',
'aif' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
@ -238,6 +238,7 @@ class DocumentManager
'wav' => 'audio/x-wav',
'wbmp' => 'image/vnd.wap.wbmp',
'wbxml' => 'application/vnd.wap.wbxml',
'webp' => 'image/webp',
'wml' => 'text/vnd.wap.wml',
'wmlc' => 'application/vnd.wap.wmlc',
'wmls' => 'text/vnd.wap.wmlscript',
@ -263,7 +264,7 @@ class DocumentManager
];
if ($filename === true) {
return $mime_types;
return $mimeTypes;
}
//get the extension of the file
@ -278,11 +279,10 @@ class DocumentManager
}
//if the extension is found, return the content type
if (isset($mime_types[$extension])) {
return $mime_types[$extension];
if (isset($mimeTypes[$extension])) {
return $mimeTypes[$extension];
}
//else return octet-stream
return 'application/octet-stream';
}
@ -475,13 +475,13 @@ class DocumentManager
$userGroupFilter = '';
if (!is_null($toUserId)) {
$toUserId = intval($toUserId);
$toUserId = (int) $toUserId;
$userGroupFilter = "last.to_user_id = $toUserId";
if (empty($toUserId)) {
$userGroupFilter = " (last.to_user_id = 0 OR last.to_user_id IS NULL) ";
}
} else {
$toGroupId = intval($toGroupId);
$toGroupId = (int) $toGroupId;
$userGroupFilter = "last.to_group_id = $toGroupId";
if (empty($toGroupId)) {
$userGroupFilter = "( last.to_group_id = 0 OR last.to_group_id IS NULL) ";
@ -1349,6 +1349,10 @@ class DocumentManager
$row['parent_id'] = '0';
} else {
$row['parent_id'] = self::get_document_id($course_info, dirname($row['path']), $session_id);
if (empty($row['parent_id'])) {
// Try one more with session id = 0
$row['parent_id'] = self::get_document_id($course_info, dirname($row['path']), 0);
}
}
$parents = [];
@ -3143,6 +3147,7 @@ class DocumentManager
* @param bool $showInvisibleFiles
* @param bool $showOnlyFolders
* @param int $folderId
* @param bool $addCloseButton
*
* @return string
*/
@ -3156,7 +3161,8 @@ class DocumentManager
$overwrite_url = '',
$showInvisibleFiles = false,
$showOnlyFolders = false,
$folderId = false
$folderId = false,
$addCloseButton = true
) {
if (empty($course_info['real_id']) || empty($course_info['code']) || !is_array($course_info)) {
return '';
@ -3177,7 +3183,7 @@ class DocumentManager
}
// Condition for the session
$session_id = intval($session_id);
$session_id = (int) $session_id;
if (!$user_in_course) {
if (empty($session_id)) {
@ -3225,7 +3231,6 @@ class DocumentManager
}
$folderCondition = " AND docs.path LIKE '/%' ";
if (!api_is_allowed_to_edit()) {
$protectedFolders = self::getProtectedFolderFromStudent();
foreach ($protectedFolders as $folder) {
@ -3514,30 +3519,43 @@ class DocumentManager
/**
* @param int $doc_id
* @param string $course_code
* @param int $session_id
* @param array $courseInfo
* @param int $sessionId
* @param int $user_id
* @param int $groupId iid
* @param bool $checkParentVisibility
*
* @return bool
*/
public static function check_visibility_tree(
$doc_id,
$course_code,
$session_id,
$courseInfo,
$sessionId,
$user_id,
$groupId = 0
$groupId = 0,
$checkParentVisibility = true
) {
if (empty($courseInfo)) {
return false;
}
$courseCode = $courseInfo['code'];
if (empty($courseCode)) {
return false;
}
$document_data = self::get_document_data_by_id(
$doc_id,
$course_code,
$courseCode,
null,
$session_id
$sessionId
);
if ($session_id != 0 && !$document_data) {
if ($sessionId != 0 && !$document_data) {
$document_data = self::get_document_data_by_id(
$doc_id,
$course_code,
$courseCode,
null,
0
);
@ -3545,30 +3563,34 @@ class DocumentManager
if (!empty($document_data)) {
// If admin or course teacher, allow anyway
if (api_is_platform_admin() || CourseManager::is_course_teacher($user_id, $course_code)) {
if (api_is_platform_admin() || CourseManager::is_course_teacher($user_id, $courseCode)) {
return true;
}
$course_info = api_get_course_info($course_code);
if ($document_data['parent_id'] == false || empty($document_data['parent_id'])) {
if (!empty($groupId)) {
return true;
}
$visible = self::is_visible_by_id($doc_id, $course_info, $session_id, $user_id);
$visible = self::is_visible_by_id($doc_id, $courseInfo, $sessionId, $user_id);
return $visible;
} else {
$visible = self::is_visible_by_id($doc_id, $course_info, $session_id, $user_id);
$visible = self::is_visible_by_id($doc_id, $courseInfo, $sessionId, $user_id);
if (!$visible) {
return false;
} else {
return self::check_visibility_tree(
$document_data['parent_id'],
$course_code,
$session_id,
$user_id,
$groupId
);
if ($checkParentVisibility) {
return self::check_visibility_tree(
$document_data['parent_id'],
$courseInfo,
$sessionId,
$user_id,
$groupId
);
}
return true;
}
}
} else {
@ -4264,7 +4286,6 @@ class DocumentManager
file_exists($documentData['absolute_path'])
) {
$mp3FilePath = self::convertWavToMp3($documentData['absolute_path']);
error_log($mp3FilePath);
if (!empty($mp3FilePath) && file_exists($mp3FilePath)) {
$documentId = self::addFileToDocumentTool(
@ -4824,6 +4845,9 @@ class DocumentManager
$attributes = ['onchange' => 'javascript: document.selector.submit();'];
}
$form->addElement('hidden', 'cidReq', api_get_course_id());
$form->addElement('hidden', 'id_session', api_get_session_id());
$form->addElement('hidden', 'gidReq', api_get_group_id());
$parent_select = $form->addSelect(
$selectName,
get_lang('CurrentDirectory'),
@ -5508,10 +5532,8 @@ class DocumentManager
($folder != $move_file) &&
(substr($folder, 0, strlen($move_file) + 1) != $move_file.'/')
) {
$path_displayed = $folder;
// If document title is used, we have to display titles instead of real paths...
$path_displayed = self::get_titles_of_path($folder);
if (empty($path_displayed)) {
$path_displayed = get_lang('Untitled');
}
@ -5528,8 +5550,7 @@ class DocumentManager
// Cannot copy dir into his own subdir
$path_displayed = self::get_titles_of_path($folder);
$display_folder = substr($path_displayed, strlen($group_dir));
$display_folder = ($display_folder == '') ? get_lang('Documents') : $display_folder;
//$form .= '<option value="'.$folder.'">'.$display_folder.'</option>';
$display_folder = ($display_folder == '') ? get_lang('Documents') : $display_folder;
$options[$folder] = $display_folder;
}
}

@ -949,6 +949,8 @@ class Event
* @param int $lp_id
* @param array $course
* @param int $session_id
*
* @return bool
*/
public static function delete_student_lp_events(
$user_id,
@ -961,7 +963,14 @@ class Event
$lpInteraction = Database::get_course_table(TABLE_LP_IV_INTERACTION);
$lpObjective = Database::get_course_table(TABLE_LP_IV_OBJECTIVE);
if (empty($course)) {
return false;
}
$course_id = $course['real_id'];
$user_id = (int) $user_id;
$lp_id = (int) $lp_id;
$session_id = (int) $session_id;
if (empty($course_id)) {
$course_id = api_get_course_int_id();
@ -977,10 +986,6 @@ class Event
TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING
);
$user_id = (int) $user_id;
$lp_id = (int) $lp_id;
$session_id = (int) $session_id;
//Make sure we have the exact lp_view_id
$sql = "SELECT id FROM $lp_view_table
WHERE
@ -1007,6 +1012,18 @@ class Event
Database::query($sql);
}
if (api_get_configuration_value('lp_minimum_time')) {
$sql = "DELETE FROM track_e_access_complete
WHERE
tool = 'learnpath' AND
c_id = $course_id AND
tool_id = $lp_id AND
user_id = $user_id AND
session_id = $session_id
";
Database::query($sql);
}
$sql = "DELETE FROM $lp_view_table
WHERE
c_id = $course_id AND
@ -1052,6 +1069,8 @@ class Event
$course_id,
$session_id
);
return true;
}
/**
@ -2158,4 +2177,45 @@ class Event
return false;
}
/**
* Register the logout of the course (usually when logging out of the platform)
* from the track_e_access_complete table.
*
* @param array $logInfo Information stored by local.inc.php
*
* @return bool
*/
public static function registerLog($logInfo)
{
if (!api_get_configuration_value('lp_minimum_time')) {
return false;
}
$loginAs = (int) (Session::read('login_as') === true);
$logInfo['user_id'] = api_get_user_id();
$logInfo['date_reg'] = api_get_utc_datetime();
$logInfo['tool'] = !empty($logInfo['tool']) ? $logInfo['tool'] : '';
$logInfo['tool_id'] = !empty($logInfo['tool_id']) ? (int) $logInfo['tool_id'] : 0;
$logInfo['tool_id_detail'] = !empty($logInfo['tool_id_detail']) ? (int) $logInfo['tool_id_detail'] : 0;
$logInfo['action'] = !empty($logInfo['action']) ? $logInfo['action'] : '';
$logInfo['action_details'] = !empty($logInfo['action_details']) ? $logInfo['action_details'] : '';
$logInfo['ip_user'] = api_get_real_ip();
$logInfo['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
$logInfo['session_id'] = api_get_session_id();
$logInfo['c_id'] = api_get_course_int_id();
$logInfo['ch_sid'] = session_id();
$logInfo['login_as'] = $loginAs;
$logInfo['info'] = !empty($logInfo['info']) ? $logInfo['info'] : '';
$logInfo['url'] = $_SERVER['REQUEST_URI'];
$logInfo['current_id'] = Session::read('last_id', 0);
$id = Database::insert('track_e_access_complete', $logInfo);
if ($id && empty($logInfo['current_id'])) {
Session::write('last_id', $id);
}
return true;
}
}

@ -80,7 +80,7 @@ class ExerciseLib
// shown at the end of the given time, so hide for now
$titleToDisplay = Display::div(
$current_item.'. '.get_lang('ReadingComprehension'),
['class' => 'title']
['class' => 'question_title']
);
}
echo $titleToDisplay;
@ -88,7 +88,7 @@ class ExerciseLib
if (!empty($questionDescription) && $answerType != READING_COMPREHENSION) {
echo Display::div(
$questionDescription,
['class' => 'description']
['class' => 'question_description']
);
}
}
@ -97,7 +97,7 @@ class ExerciseLib
return '';
}
echo '<div class="options">';
echo '<div class="question_options">';
// construction of the Answer object (also gets all answers details)
$objAnswerTmp = new Answer($questionId, api_get_course_int_id(), $exercise);
$nbrAnswers = $objAnswerTmp->selectNbrAnswers();
@ -243,7 +243,7 @@ class ExerciseLib
if ($show_comment) {
$header .= Display::tag('th', get_lang('Feedback'));
}
$s .= '<table class="table table-hover">';
$s .= '<table class="table table-hover table-striped">';
$s .= Display::tag(
'tr',
$header,
@ -428,7 +428,7 @@ class ExerciseLib
if ($exercise->feedback_type == EXERCISE_FEEDBACK_TYPE_END) {
$header .= Display::tag('th', get_lang('Feedback'));
}
$s .= '<table class="table">';
$s .= '<table class="table table-hover table-striped">';
$s .= Display::tag(
'tr',
$header,
@ -452,7 +452,7 @@ class ExerciseLib
$hidingClass = 'hide-reading-answers';
$s .= Display::div(
$objQuestionTmp->selectTitle(),
['class' => 'title '.$hidingClass]
['class' => 'question_title '.$hidingClass]
);
}
@ -516,7 +516,6 @@ class ExerciseLib
$answer_input = null;
$attributes['class'] = 'checkradios';
if ($answerType == UNIQUE_ANSWER_IMAGE) {
$attributes['class'] = '';
$attributes['style'] = 'display: none;';
@ -4429,7 +4428,6 @@ EOT;
// Hide results
$show_results = false;
$show_only_score = false;
if ($objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS) {
$show_results = true;
}
@ -4456,9 +4454,19 @@ EOT;
}
$showTotalScoreAndUserChoicesInLastAttempt = true;
if ($objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$showTotalScore = true;
$showQuestionScore = true;
if (in_array(
$objExercise->results_disabled,
[
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
])
) {
$show_only_score = true;
$show_results = true;
$numberAttempts = 0;
if ($objExercise->attempts > 0) {
$attempts = Event::getExerciseResultsByUser(
api_get_user_id(),
@ -4469,22 +4477,32 @@ EOT;
$exercise_stat_info['orig_lp_item_id'],
'desc'
);
if ($attempts) {
$numberAttempts = count($attempts);
} else {
$numberAttempts = 0;
}
if ($save_user_result) {
$numberAttempts++;
}
$showTotalScore = false;
$showTotalScoreAndUserChoicesInLastAttempt = false;
if ($numberAttempts >= $objExercise->attempts) {
$showTotalScore = true;
$show_results = true;
$show_only_score = false;
$showTotalScoreAndUserChoicesInLastAttempt = true;
} else {
$showTotalScoreAndUserChoicesInLastAttempt = false;
}
}
if ($objExercise->results_disabled == RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK) {
$show_only_score = false;
$show_results = true;
$show_all_but_expected_answer = false;
$showTotalScore = false;
$showQuestionScore = false;
if ($numberAttempts >= $objExercise->attempts) {
$showTotalScore = true;
$showQuestionScore = true;
}
}
}
@ -4667,6 +4685,11 @@ EOT;
$question_content = '';
if ($show_results) {
$question_content = '<div class="question_row_answer">';
if ($showQuestionScore == false) {
$score = [];
}
// Shows question title an description
$question_content .= $objQuestionTmp->return_header(
$objExercise,
@ -4698,7 +4721,7 @@ EOT;
}
$totalScoreText = null;
if ($show_results || $show_only_score) {
if (($show_results || $show_only_score) && $showTotalScore) {
if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
echo '<h1 style="text-align : center; margin : 20px 0;">'.get_lang('YourResults').'</h1><br />';
}

@ -80,7 +80,7 @@ class ExerciseShowFunctions
$answer,
$id,
$questionId,
$results_disabled,
$resultsDisabled,
$showTotalScoreAndUserChoices,
$expectedChoice = '',
$choice = '',
@ -139,7 +139,7 @@ class ExerciseShowFunctions
$exe_id,
$questionId,
$questionScore = null,
$results_disabled = 0
$resultsDisabled = 0
) {
$comments = Event::get_comments($exe_id, $questionId);
@ -165,7 +165,7 @@ class ExerciseShowFunctions
* @param $id
* @param $questionId
* @param null $fileUrl
* @param int $results_disabled
* @param int $resultsDisabled
* @param int $questionScore
*/
public static function display_oral_expression_answer(
@ -174,7 +174,7 @@ class ExerciseShowFunctions
$id,
$questionId,
$fileUrl = null,
$results_disabled = 0,
$resultsDisabled = 0,
$questionScore = 0
) {
if (isset($fileUrl)) {
@ -238,15 +238,19 @@ class ExerciseShowFunctions
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && $resultsDisabled == 2) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
switch ($resultsDisabled) {
case RESULT_DISABLE_SHOW_SCORE_ONLY:
if ($feedback_type == 0) {
$hide_expected_answer = true;
}
break;
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
break;
}
$hotspot_colors = [
@ -339,15 +343,19 @@ class ExerciseShowFunctions
}
$hide_expected_answer = false;
if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
switch ($resultsDisabled) {
case RESULT_DISABLE_SHOW_SCORE_ONLY:
if ($feedback_type == 0) {
$hide_expected_answer = true;
}
break;
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
break;
}
$icon = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
@ -433,15 +441,19 @@ class ExerciseShowFunctions
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
switch ($resultsDisabled) {
case RESULT_DISABLE_SHOW_SCORE_ONLY:
if ($feedback_type == 0) {
$hide_expected_answer = true;
}
break;
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
break;
}
echo '<tr><td width="5%">';
$course_id = api_get_course_int_id();
@ -613,15 +625,19 @@ class ExerciseShowFunctions
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
switch ($resultsDisabled) {
case RESULT_DISABLE_SHOW_SCORE_ONLY:
if ($feedback_type == 0) {
$hide_expected_answer = true;
}
break;
case RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
break;
}
echo '<tr><td width="5%">';
@ -690,14 +706,14 @@ class ExerciseShowFunctions
* @param $exe_id
* @param $questionId
* @param null $questionScore
* @param int $results_disabled
* @param int $resultsDisabled
*/
public static function displayAnnotationAnswer(
$feedback_type,
$exe_id,
$questionId,
$questionScore = null,
$results_disabled = 0
$resultsDisabled = 0
) {
$comments = Event::get_comments($exe_id, $questionId);
if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {

@ -109,6 +109,7 @@ $(document).ready(function() {
src = url+'&type=link&src='+src;
src = src.replace('https', 'http');
$(this).attr('href', src);
$(this).attr('target', '_blank');
var myAnchor = $('<a><img width="16px" src="'+iconPath+'link-external.png "/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
$(this).after(myAnchor);
$(this).after('-');

@ -131,6 +131,14 @@ function online_logout($user_id = null, $logout_redirect = false)
WHERE login_id='$i_id_last_connection'";
Database::query($sql);
}
$logInfo = [
'tool' => 'logout',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => '',
'info' => '',
];
Event::registerLog($logInfo);
UserManager::loginDelete($user_id);
@ -168,8 +176,15 @@ function online_logout($user_id = null, $logout_redirect = false)
session_regenerate_id();
Session::destroy();
$pluginKeycloak = api_get_plugin_setting('keycloak', 'tool_enable') === 'true';
if ($pluginKeycloak && $uinfo['auth_source'] === 'keycloack') {
$pluginUrl = api_get_path(WEB_PLUGIN_PATH).'keycloak/start.php?slo';
header('Location: '.$pluginUrl);
exit;
}
if ($logout_redirect) {
header("Location: ".$url);
header("Location: $url");
exit;
}
}

@ -896,12 +896,16 @@ class PDF
continue;
}
// It's a reference to a file in the system, do not change it
if (file_exists($src)) {
continue;
}
if (strpos($src, '/main/default_course_document') === 0) {
$element->setAttribute(
'src',
str_replace('/main/default_course_document', $sysCodePath.'default_course_document', $src)
);
continue;
}
@ -910,7 +914,6 @@ class PDF
'src',
str_replace('/main/img/', $sysCodePath.'img/', $src)
);
continue;
}
@ -919,7 +922,6 @@ class PDF
'src',
str_replace('/app/upload/', $sysUploadPath, $src)
);
continue;
}

@ -731,6 +731,9 @@ class HTML_QuickForm_advmultiselect extends HTML_QuickForm_select
$strHtmlSelected = "<select$attrSelected>";
if ($selected_count > 0) {
foreach ($arrHtmlSelected as $data) {
if (!is_array($data)) {
continue;
}
$attribute = null;
if (isset($data['attr'])) {
$attribute = $this->_getAttrString($data['attr']);

@ -152,14 +152,16 @@ class SocialManager extends UserManager
$search_name = null,
$load_extra_info = true
) {
$user_id = (int) $user_id;
$list_ids_friends = [];
$tbl_my_friend = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
$tbl_my_user = Database::get_main_table(TABLE_MAIN_USER);
$sql = 'SELECT friend_user_id FROM '.$tbl_my_friend.'
WHERE
relation_type NOT IN ('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND
friend_user_id<>'.((int) $user_id).' AND
user_id='.((int) $user_id);
friend_user_id<>'.$user_id.' AND
user_id='.$user_id;
if (isset($id_group) && $id_group > 0) {
$sql .= ' AND relation_type='.$id_group;
}
@ -309,17 +311,17 @@ class SocialManager extends UserManager
*
* @author isaac flores paz
*
* @param int user receiver id
* @param int $userId user receiver id
*
* @return int
*/
public static function get_message_number_invitation_by_user_id($user_receiver_id)
public static function get_message_number_invitation_by_user_id($userId)
{
$table = Database::get_main_table(TABLE_MESSAGE);
$user_receiver_id = (int) $user_receiver_id;
$userId = (int) $userId;
$sql = 'SELECT COUNT(*) as count_message_in_box FROM '.$table.'
WHERE
user_receiver_id='.$user_receiver_id.' AND
user_receiver_id='.$userId.' AND
msg_status='.MESSAGE_STATUS_INVITATION_PENDING;
$res = Database::query($sql);
$row = Database::fetch_array($res, 'ASSOC');
@ -333,16 +335,17 @@ class SocialManager extends UserManager
/**
* Get number of messages sent to other users.
*
* @param int $sender_id
* @param int $userId
*
* @return int
*/
public static function getCountMessagesSent($sender_id)
public static function getCountMessagesSent($userId)
{
$userId = (int) $userId;
$table = Database::get_main_table(TABLE_MESSAGE);
$sql = 'SELECT COUNT(*) FROM '.$table.'
WHERE
user_sender_id='.intval($sender_id).' AND
user_sender_id='.$userId.' AND
msg_status < 5';
$res = Database::query($sql);
$row = Database::fetch_row($res);
@ -405,13 +408,14 @@ class SocialManager extends UserManager
* @author isaac flores paz
*
* @param int $userId
* @param $limit
* @param int $limit
*
* @return array
*/
public static function get_list_invitation_of_friends_by_user_id($userId, $limit)
{
$userId = (int) $userId;
$limit = (int) $limit;
if (empty($userId)) {
return [];
@ -478,6 +482,8 @@ class SocialManager extends UserManager
*/
public static function getCountInvitationSent($userId)
{
$userId = (int) $userId;
if (empty($userId)) {
return 0;
}
@ -486,7 +492,7 @@ class SocialManager extends UserManager
$sql = 'SELECT count(user_receiver_id) count
FROM '.$table.'
WHERE
user_sender_id = '.intval($userId).' AND
user_sender_id = '.$userId.' AND
msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
$res = Database::query($sql);
if (Database::num_rows($res)) {
@ -701,6 +707,8 @@ class SocialManager extends UserManager
public static function get_logged_user_course_html($my_course, $count)
{
$result = '';
$count = (int) $count;
// Table definitions
$main_user_table = Database::get_main_table(TABLE_MAIN_USER);
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
@ -1253,7 +1261,7 @@ class SocialManager extends UserManager
*/
public static function display_user_list($user_list, $wrap = true)
{
$html = null;
$html = '';
if (isset($_GET['id']) || count($user_list) < 1) {
return false;
@ -1522,7 +1530,7 @@ class SocialManager extends UserManager
* Gets all messages from someone's wall (within specific limits).
*
* @param int $userId id of wall shown
* @param string $messageStatus status wall message
* @param int $messageStatus status wall message
* @param int|string $parentId id message (Post main)
* @param string $start Date from which we want to show the messages, in UTC time
* @param int $limit Limit for the number of parent messages we want to show
@ -1546,10 +1554,11 @@ class SocialManager extends UserManager
$tblMessage = Database::get_main_table(TABLE_MESSAGE);
$tblMessageAttachment = Database::get_main_table(TABLE_MESSAGE_ATTACHMENT);
$userId = intval($userId);
$parentId = (int) $parentId;
$userId = (int) $userId;
$start = Database::escape_string($start);
$limit = intval($limit);
$offset = (int) $offset;
$messageStatus = (int) $messageStatus;
$sql = "SELECT
id,
@ -1591,7 +1600,7 @@ class SocialManager extends UserManager
*
* @param int $userId USER ID of the person's wall
* @param int $friendId id person
* @param int $idMessage id message
* @param int $messageId id message
* @param string $start Start date (from when we want the messages until today)
* @param int $limit Limit to the number of messages we want
* @param int $offset Wall messages offset
@ -1601,7 +1610,7 @@ class SocialManager extends UserManager
public static function getWallMessagesHTML(
$userId,
$friendId,
$idMessage,
$messageId,
$start = null,
$limit = 10,
$offset = 0
@ -1614,7 +1623,7 @@ class SocialManager extends UserManager
$messages = self::getWallMessages(
$userId,
MESSAGE_STATUS_WALL,
$idMessage,
$messageId,
$start,
$limit,
$offset
@ -1660,7 +1669,7 @@ class SocialManager extends UserManager
$media .= Display::url(
Display::returnFontAwesomeIcon('trash'),
$url,
['title' => get_lang("SocialMessageDelete")]
['title' => get_lang('SocialMessageDelete')]
);
$media .= '</div>';
$media .= '</div>';
@ -1674,7 +1683,7 @@ class SocialManager extends UserManager
$formattedList .= '<div class="mediapost-form">';
$formattedList .= '<form name="social_wall_message" method="POST">
<label for="social_wall_new_msg" class="hide">'.get_lang('SocialWriteNewComment').'</label>
<input type="hidden" name = "messageId" value="'.$idMessage.'" />
<input type="hidden" name = "messageId" value="'.$messageId.'" />
<textarea placeholder="'.get_lang('SocialWriteNewComment').
'" name="social_wall_new_msg" rows="1" style="width:80%;" ></textarea>
<button type="submit" name="social_wall_new_msg_submit"
@ -2153,6 +2162,9 @@ class SocialManager extends UserManager
*/
private static function headerMessagePost($authorId, $receiverId, $users, $message, $isOwnWall = false)
{
$authorId = (int) $authorId;
$receiverId = (int) $receiverId;
$date = api_get_local_time($message['send_date']);
$avatarAuthor = $users[$authorId]['avatar'];
$urlAuthor = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$authorId;
@ -2176,7 +2188,6 @@ class SocialManager extends UserManager
if (!empty($message['path'])) {
$imageBig = UserManager::getUserPicture($authorId, USER_IMAGE_SIZE_BIG);
$imageSmall = UserManager::getUserPicture($authorId, USER_IMAGE_SIZE_SMALL);
$wallImage = '<a class="thumbnail ajax" href="'.$imageBig.'"><img src="'.$imageSmall.'"></a>';
}

@ -1097,7 +1097,11 @@ class SortableTableFromArray extends SortableTable
if (isset($this->total_number_of_items) && !empty($this->total_number_of_items)) {
return $this->total_number_of_items;
} else {
return count($this->table_data);
if (!empty($this->table_data)) {
return count($this->table_data);
}
return 0;
}
}
}

@ -390,20 +390,19 @@ class Template
$this->assign('show_toolbar', $show_toolbar);
//Only if course is available
$show_course_shortcut = null;
$show_course_navigation_menu = null;
$courseToolBar = '';
$show_course_navigation_menu = '';
if (!empty($this->course_id) && $this->user_is_logged_in) {
if (api_get_setting('show_toolshortcuts') !== 'false') {
//Course toolbar
$show_course_shortcut = CourseHome::getCourseToolBar();
// Course toolbar
$courseToolBar = CourseHome::show_navigation_tool_shortcuts();
}
if (api_get_setting('show_navigation_menu') !== 'false') {
//Course toolbar
$show_course_navigation_menu = CourseHome::show_navigation_menu();
}
}
$this->assign('show_course_shortcut', $show_course_shortcut);
$this->assign('show_course_shortcut', $courseToolBar);
$this->assign('show_course_navigation_menu', $show_course_navigation_menu);
}
@ -686,7 +685,9 @@ class Template
// Logo
$logo = return_logo($this->theme);
$logoPdf = return_logo($this->theme, false);
$this->assign('logo', $logo);
$this->assign('logo_pdf', $logoPdf);
$this->assign('show_media_element', 1);
}
@ -1362,7 +1363,6 @@ class Template
$this->assign('prefetch', $prefetch);
$this->assign('text_direction', api_get_text_direction());
$this->assign('section_name', 'section-'.$this_section);
$this->assignFavIcon(); //Set a 'favico' var for the template
$this->setHelp();
$this->assignBugNotification(); //Prepare the 'bug_notification' var for the template
@ -1612,6 +1612,28 @@ class Template
return true;
}
/**
* Assign HTML code to the 'accessibility' template variable (usually shown above top menu).
*
* @return bool Always return true (even if empty string)
*/
private function assignAccessibilityBlock()
{
$resize = '';
if (api_get_setting('accessibility_font_resize') == 'true') {
$resize .= '<div class="resize_font">';
$resize .= '<div class="btn-group">';
$resize .= '<a title="'.get_lang('DecreaseFontSize').'" href="#" class="decrease_font btn btn-default"><em class="fa fa-font"></em></a>';
$resize .= '<a title="'.get_lang('ResetFontSize').'" href="#" class="reset_font btn btn-default"><em class="fa fa-font"></em></a>';
$resize .= '<a title="'.get_lang('IncreaseFontSize').'" href="#" class="increase_font btn btn-default"><em class="fa fa-font"></em></a>';
$resize .= '</div>';
$resize .= '</div>';
}
$this->assign('accessibility', $resize);
return true;
}
/**
* Assign HTML code to the 'social_meta' template variable (usually shown above top menu).
*

@ -435,12 +435,21 @@ class Tracking
$lesson_status = $row['mystatus'];
$score = $row['myscore'];
$time_for_total = $row['mytime'];
if (api_get_configuration_value('lp_minimum_time')) {
$timeCourse = self::getCalculateTime($user_id, $course_id, $session_id);
Session::write('trackTimeCourse', $timeCourse);
$lp_time = $timeCourse[TOOL_LEARNPATH];
$lpTime = (int) $lp_time[$lp_id];
$time_for_total = $lpTime;
}
$time = learnpathItem::getScormTimeFromParameter('js', $row['mytime']);
if ($score == 0) {
$maxscore = $row['mymaxscore'];
} else {
if ($row['item_type'] == 'sco') {
if ($row['item_type'] === 'sco') {
if (!empty($row['myviewmaxscore']) && $row['myviewmaxscore'] > 0) {
$maxscore = $row['myviewmaxscore'];
} elseif ($row['myviewmaxscore'] === '') {
@ -1624,6 +1633,13 @@ class Tracking
return 0;
}
if (api_get_configuration_value('lp_minimum_time')) {
$courseTime = self::getCalculateTime($user_id, $courseId, $session_id);
$time = isset($courseTime['total_time']) ? $courseTime['total_time'] : 0;
return $time;
}
$session_id = (int) $session_id;
if (is_array($user_id)) {
$user_id = array_map('intval', $user_id);
@ -1791,29 +1807,54 @@ class Tracking
$session_id = 0,
$convert_date = true
) {
$student_id = intval($student_id);
$courseId = intval($courseId);
$session_id = intval($session_id);
$student_id = (int) $student_id;
$courseId = (int) $courseId;
$session_id = (int) $session_id;
$tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
$sql = 'SELECT login_course_date
FROM '.$tbl_track_login.'
WHERE
user_id = '.$student_id.' AND
c_id = '.$courseId.' AND
session_id = '.$session_id.'
ORDER BY login_course_date ASC
LIMIT 0,1';
$rs = Database::query($sql);
if (Database::num_rows($rs) > 0) {
if ($first_login_date = Database::result($rs, 0, 0)) {
if ($convert_date) {
return api_convert_and_format_date(
$first_login_date,
DATE_FORMAT_SHORT
);
} else {
return $first_login_date;
if (api_get_configuration_value('lp_minimum_time')) {
$tbl_track_e_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
$sql = 'SELECT access_date
FROM '.$tbl_track_e_access.'
WHERE access_user_id = '.$student_id.' AND
c_id = "'.$courseId.'" AND
access_session_id = '.$session_id.'
ORDER BY access_date ASC
LIMIT 0,1';
$rs = Database::query($sql);
if (Database::num_rows($rs) > 0) {
if ($last_login_date = Database::result($rs, 0, 0)) {
if (empty($last_login_date)) {
return false;
}
if ($convert_date) {
return api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT);
} else {
return $last_login_date;
}
}
}
} else {
$tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
$sql = 'SELECT login_course_date
FROM '.$tbl_track_login.'
WHERE
user_id = '.$student_id.' AND
c_id = '.$courseId.' AND
session_id = '.$session_id.'
ORDER BY login_course_date ASC
LIMIT 0,1';
$rs = Database::query($sql);
if (Database::num_rows($rs) > 0) {
if ($first_login_date = Database::result($rs, 0, 0)) {
if ($convert_date) {
return api_convert_and_format_date(
$first_login_date,
DATE_FORMAT_SHORT
);
} else {
return $first_login_date;
}
}
}
}
@ -1841,12 +1882,24 @@ class Tracking
$student_id = (int) $student_id;
$session_id = (int) $session_id;
$courseId = $courseInfo['real_id'];
if (api_get_configuration_value('lp_minimum_time')) {
// Show the last date on which the user acceed the session when it was active
$where_condition = '';
$userInfo = api_get_user_info($student_id);
if ($userInfo['status'] == 5 && $session_id > 0) {
// fin de acceso a la sesión
$sessionInfo = SessionManager::fetch($session_id);
$last_access = $sessionInfo['access_end_date'];
$where_condition = ' AND access_date < "'.$last_access.'" ';
}
$tbl_track_e_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
$sql = 'SELECT access_date
FROM '.$tbl_track_e_access.'
WHERE access_user_id = '.$student_id.' AND
c_id = "'.$courseId.'" AND
access_session_id = '.$session_id.'
access_session_id = '.$session_id.$where_condition.'
ORDER BY access_date DESC
LIMIT 0,1';
@ -1861,25 +1914,74 @@ class Tracking
$now = time();
//If the last connection is > than 7 days, the text is red
//345600 = 7 days in seconds
/*
if ($now - $last_login_date_timestamp > 604800) {
if ($convert_date) {
$last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT);
$icon = api_is_allowed_to_edit() ?
'<a href="'.api_get_path(WEB_CODE_PATH).'announcements/announcements.php?action=add&remind_inactive='.$student_id.'&cidReq='.$courseInfo['code'].'" title="'.get_lang('RemindInactiveUser').'">
'.Display::return_icon('warning.png').'
</a>'
: null;
return $icon.Display::label($last_login_date, 'warning');
'.Display::return_icon('messagebox_warning.gif').'
</a>'
: null;
return $icon.Display::label($last_login_date, 'warning');
} else {
return $last_login_date;
}
} else {
return $last_login_date;
}
} else {
*/
if ($convert_date) {
return api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT);
} else {
return $last_login_date;
}
//}
}
}
} else {
$tbl_track_e_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
$sql = 'SELECT access_date
FROM '.$tbl_track_e_access.'
WHERE access_user_id = '.$student_id.' AND
c_id = "'.$courseId.'" AND
access_session_id = '.$session_id.'
ORDER BY access_date DESC
LIMIT 0,1';
$rs = Database::query($sql);
if (Database::num_rows($rs) > 0) {
if ($last_login_date = Database::result($rs, 0, 0)) {
if (empty($last_login_date)) {
return false;
}
//see #5736
$last_login_date_timestamp = api_strtotime($last_login_date);
$now = time();
//If the last connection is > than 7 days, the text is red
//345600 = 7 days in seconds
if ($now - $last_login_date_timestamp > 604800) {
if ($convert_date) {
$last_login_date = api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT);
$icon = api_is_allowed_to_edit() ?
'<a href="'.api_get_path(
WEB_CODE_PATH
).'announcements/announcements.php?action=add&remind_inactive='.$student_id.'&cidReq='.$courseInfo['code'].'" title="'.get_lang(
'RemindInactiveUser'
).'">
'.Display::return_icon('messagebox_warning.gif').'
</a>'
: null;
return $icon.Display::label($last_login_date, 'warning');
} else {
return $last_login_date;
}
} else {
if ($convert_date) {
return api_convert_and_format_date($last_login_date, DATE_FORMAT_SHORT);
} else {
return $last_login_date;
}
}
}
}
}
@ -3642,6 +3744,8 @@ class Tracking
* @param bool $getCount
* @param string $keyword
* @param string $description
* @param string $orderByName
* @param string $orderByDirection
*
* @return mixed
*/
@ -3651,12 +3755,14 @@ class Tracking
$limit = 0,
$getCount = false,
$keyword = '',
$description = ''
$description = '',
$orderByName = '',
$orderByDirection = ''
) {
// table definition
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
$tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
$coach_id = intval($coach_id);
$coach_id = (int) $coach_id;
$select = " SELECT * FROM ";
if ($getCount) {
@ -3683,6 +3789,15 @@ class Tracking
$tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
$access_url_id = api_get_current_access_url_id();
$orderBy = '';
if (!empty($orderByName)) {
if (in_array($orderByName, ['name', 'access_start_date'])) {
$orderByDirection = in_array(strtolower($orderByDirection), ['asc', 'desc']) ? $orderByDirection : 'asc';
$orderByName = Database::escape_string($orderByName);
$orderBy .= " ORDER BY $orderByName $orderByDirection";
}
}
$sql = "
$select
(
@ -3715,7 +3830,7 @@ class Tracking
WHERE
access_url_id = $access_url_id
$keywordCondition
) as sessions $limitCondition
) as sessions $limitCondition $orderBy
";
$rs = Database::query($sql);
@ -3736,8 +3851,7 @@ class Tracking
if (!empty($sessions)) {
foreach ($sessions as &$session) {
if (empty($session['access_start_date'])
) {
if (empty($session['access_start_date'])) {
$session['status'] = get_lang('SessionActive');
} else {
$time_start = api_strtotime($session['access_start_date'], 'UTC');
@ -6679,6 +6793,167 @@ class Tracking
return $html;
}
/**
* @param int $userId
* @param int $courseId
* @param int $sessionId
*
* @return array
*/
public static function getCalculateTime($userId, $courseId, $sessionId)
{
$userId = (int) $userId;
$courseId = (int) $courseId;
$sessionId = (int) $sessionId;
if (empty($userId) || empty($courseId)) {
return [];
}
$lpTime = [];
$sql = "SELECT MIN(date_reg) min, MAX(date_reg) max
FROM track_e_access_complete
WHERE
user_id = $userId AND
c_id = $courseId AND
session_id = $sessionId AND
login_as = 0
ORDER BY date_reg ASC
LIMIT 1";
$rs = Database::query($sql);
$firstConnection = '';
$lastConnection = '';
if (Database::num_rows($rs) > 0) {
$value = Database::fetch_array($rs);
$firstConnection = $value['min'];
$lastConnection = $value['max'];
}
$sql = "SELECT * FROM track_e_access_complete
WHERE
user_id = $userId AND
c_id = $courseId AND
session_id = $sessionId AND
login_as = 0";
$res = Database::query($sql);
$reg = [];
while ($row = Database::fetch_assoc($res)) {
$reg[$row['id']] = $row;
$reg[$row['id']]['date_reg'] = strtotime($row['date_reg']);
}
$sessions = [];
foreach ($reg as $key => $value) {
$sessions[$value['current_id']][$value['tool']][] = $value;
}
$quizTime = 0;
$result = [];
$totalTime = 0;
foreach ($sessions as $listPerTool) {
$min = 0;
$max = 0;
$sessionDiff = 0;
foreach ($listPerTool as $tool => $results) {
$beforeItem = [];
foreach ($results as $item) {
if (empty($beforeItem)) {
$beforeItem = $item;
continue;
}
$partialTime = $item['date_reg'] - $beforeItem['date_reg'];
if ($item['date_reg'] > $max) {
$max = $item['date_reg'];
}
if (empty($min)) {
$min = $item['date_reg'];
}
if ($item['date_reg'] < $min) {
$min = $item['date_reg'];
}
switch ($tool) {
case TOOL_AGENDA:
case TOOL_FORUM:
case TOOL_ANNOUNCEMENT:
case TOOL_COURSE_DESCRIPTION:
case TOOL_SURVEY:
case TOOL_NOTEBOOK:
case TOOL_GRADEBOOK:
case TOOL_DROPBOX:
case 'Reports':
case 'Videoconference':
case TOOL_LINK:
case TOOL_CHAT:
case 'course-main':
if (!isset($result[$tool])) {
$result[$tool] = 0;
}
$result[$tool] += $partialTime;
break;
case TOOL_LEARNPATH:
if ($item['tool_id'] != $beforeItem['tool_id']) {
continue;
}
if (!isset($lpTime[$item['tool_id']])) {
$lpTime[$item['tool_id']] = 0;
}
$lpTime[$item['tool_id']] += $partialTime;
if ($item['tool_id'] == 51) {
//$counter++;
//var_dump($beforeItem, $item);
/*var_dump(
api_get_utc_datetime($item['date_reg']),
api_get_utc_datetime($beforeItem['date_reg'])
);*/
/*var_dump(
$counter.'-'.$beforeItem['id'].'-'.$item['id'].'-'.$partialTime.'-'.api_time_to_hms($lpTime[$item['tool_id']])
);*/
}
break;
case TOOL_QUIZ:
if (!isset($lpTime[$item['action_details']])) {
$lpTime[$item['action_details']] = 0;
}
if ($beforeItem['action'] == 'learnpath_id') {
$lpTime[$item['action_details']] += $partialTime;
} else {
$quizTime += $partialTime;
}
break;
}
$beforeItem = $item;
}
}
$sessionDiff += $max - $min;
if ($sessionDiff > 0) {
$totalTime += $sessionDiff;
}
}
$totalLp = 0;
foreach ($lpTime as $value) {
$totalLp += $value;
}
$result[TOOL_LEARNPATH] = $lpTime;
$result[TOOL_QUIZ] = $quizTime;
$result['total_learnpath'] = $totalLp;
$result['total_time'] = $totalTime;
$result['number_connections'] = count($sessions);
$result['first'] = $firstConnection;
$result['last'] = $lastConnection;
return $result;
}
/**
* Gets the IP of a given user, using the last login before the given date.
*

@ -407,6 +407,7 @@ class UserGroup extends Model
/**
* @param array $options
* @param int $type
*
* @return array
*/
@ -550,7 +551,8 @@ class UserGroup extends Model
],
],
];
$from = $this->usergroup_rel_course_table." as c INNER JOIN ".$this->access_url_rel_usergroup." a
$from = $this->usergroup_rel_course_table." as c
INNER JOIN ".$this->access_url_rel_usergroup." a
ON c.usergroup_id = a.usergroup_id";
} else {
$options = ['where' => ['c.course_id = ?' => $course_id]];
@ -1356,11 +1358,14 @@ class UserGroup extends Model
* Creates new group pictures in various sizes of a user, or deletes user pfotos.
* Note: This method relies on configuration setting from main/inc/conf/profile.conf.php.
*
* @param $group_id
* @param int The group id
* @param string $file The common file name for the newly created photos.
* It will be checked and modified for compatibility with the file system.
* If full name is provided, path component is ignored.
* If an empty name is provided, then old user photos are deleted only,
*
* @see UserManager::delete_user_picture() as the prefered way for deletion.
*
* @param string $source_file the full system name of the image from which user photos will be created
* @param string $cropParameters
*
@ -1372,6 +1377,8 @@ class UserGroup extends Model
public function update_group_picture($group_id, $file = null, $source_file = null, $cropParameters = null)
{
// Validation 1.
$group_id = (int) $group_id;
if (empty($group_id)) {
return false;
}
@ -1382,6 +1389,7 @@ class UserGroup extends Model
// User-reserved directory where photos have to be placed.
$path_info = self::get_group_picture_path_by_id($group_id, 'system', true);
$path = $path_info['dir'];
// If this directory does not exist - we create it.
@ -1734,12 +1742,12 @@ class UserGroup extends Model
default: // Base: empty, the result path below will be relative.
$base = '';
}
$id = (int) $id;
if (empty($id) || empty($type)) {
return $anonymous ? ['dir' => $base.'img/', 'file' => 'unknown.jpg'] : ['dir' => '', 'file' => ''];
}
$id = (int) $id;
$group_table = Database::get_main_table(TABLE_USERGROUP);
$sql = "SELECT picture FROM $group_table WHERE id = ".$id;
$res = Database::query($sql);
@ -1936,7 +1944,7 @@ class UserGroup extends Model
{
$table_url_rel_group = $this->usergroup_rel_user_table;
$result_array = [];
$relation_type = intval($relation_type);
$relation_type = (int) $relation_type;
if (is_array($user_list) && is_array($group_list)) {
foreach ($group_list as $group_id) {
@ -1947,7 +1955,7 @@ class UserGroup extends Model
SET
user_id = ".intval($user_id).",
usergroup_id = ".intval($group_id).",
relation_type = ".intval($relation_type);
relation_type = ".$relation_type;
$result = Database::query($sql);
if ($result) {
@ -2053,15 +2061,16 @@ class UserGroup extends Model
*
* @author Julio Montoya
* */
public function get_groups_by_user($user_id = '', $relation_type = GROUP_USER_PERMISSION_READER, $with_image = false)
public function get_groups_by_user($user_id, $relation_type = GROUP_USER_PERMISSION_READER, $with_image = false)
{
$table_group_rel_user = $this->usergroup_rel_user_table;
$tbl_group = $this->table;
$user_id = (int) $user_id;
if ($relation_type == 0) {
$relationCondition = '';
} else {
$relation_type = intval($relation_type);
$relation_type = (int) $relation_type;
$relationCondition = " AND gu.relation_type = $relation_type ";
}
@ -2512,7 +2521,6 @@ class UserGroup extends Model
$from = intval($from);
$number_of_items = intval($number_of_items);
//$sql .= " ORDER BY col$column $direction ";
$sql .= " LIMIT $from,$number_of_items";
$res = Database::query($sql);
@ -2535,6 +2543,8 @@ class UserGroup extends Model
public static function get_parent_groups($group_id)
{
$t_rel_group = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);
$group_id = (int) $group_id;
$max_level = 10;
$select_part = "SELECT ";
$cond_part = '';
@ -2581,7 +2591,7 @@ class UserGroup extends Model
$relationType = GROUP_USER_PERMISSION_ADMIN,
$includeSubgroupsUsers = true
) {
$userId = intval($userId);
$userId = (int) $userId;
$groups = $this->get_groups_by_user($userId, $relationType);
$groupsId = array_keys($groups);
$subgroupsId = [];
@ -2632,7 +2642,7 @@ class UserGroup extends Model
public static function getGroupsByDepthLevel($groupId, $levels = 10)
{
$groups = [];
$groupId = intval($groupId);
$groupId = (int) $groupId;
$groupTable = Database::get_main_table(TABLE_USERGROUP);
$groupRelGroupTable = Database::get_main_table(TABLE_USERGROUP_REL_USERGROUP);

@ -3083,7 +3083,6 @@ class UserManager
$collapsableLink = api_get_path(WEB_PATH).'user_portal.php?action=collapse_session';
$categories = [];
foreach ($sessionData as $row) {
$session_id = $row['id'];
$coachList = SessionManager::getCoachesBySession($session_id);
@ -5499,7 +5498,28 @@ class UserManager
}
/**
* Subscribe boss to students.
* @param int $userId
*
* @return bool
*/
public static function removeAllBossFromStudent($userId)
{
$userId = (int) $userId;
if (empty($userId)) {
return false;
}
$userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
$sql = "DELETE FROM $userRelUserTable
WHERE user_id = $userId AND relation_type = ".USER_RELATION_TYPE_BOSS;
Database::query($sql);
return true;
}
/**
* Subscribe boss to students, if $bossList is empty then the boss list will be empty too.
*
* @param int $studentId
* @param array $bossList
@ -5513,7 +5533,8 @@ class UserManager
$sendNotification = false
) {
$inserted = 0;
if ($bossList) {
if (!empty($bossList)) {
sort($bossList);
$studentId = (int) $studentId;
$studentInfo = api_get_user_info($studentId);
@ -5521,10 +5542,17 @@ class UserManager
return false;
}
$previousBossList = self::getStudentBossList($studentId);
$previousBossList = !empty($previousBossList) ? array_column($previousBossList, 'boss_id') : [];
sort($previousBossList);
// Boss list is the same, nothing changed.
if ($bossList == $previousBossList) {
return false;
}
$userRelUserTable = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
$sql = "DELETE FROM $userRelUserTable
WHERE user_id = $studentId AND relation_type = ".USER_RELATION_TYPE_BOSS;
Database::query($sql);
self::removeAllBossFromStudent($studentId);
foreach ($bossList as $bossId) {
$bossId = (int) $bossId;
@ -5548,6 +5576,8 @@ class UserManager
$inserted++;
}
}
} else {
self::removeAllBossFromStudent($studentId);
}
return $inserted;
@ -5926,7 +5956,7 @@ SQL;
*/
public static function loginAsUser($userId, $checkIfUserCanLoginAs = true)
{
$userId = intval($userId);
$userId = (int) $userId;
$userInfo = api_get_user_info($userId);
// Check if the user is allowed to 'login_as'
@ -5940,6 +5970,15 @@ SQL;
}
if ($userId) {
$logInfo = [
'tool' => 'logout',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => '',
'info' => 'Change user (login as)',
];
Event::registerLog($logInfo);
// Logout the current user
self::loginDelete(api_get_user_id());
@ -5966,6 +6005,15 @@ SQL;
// will be useful later to know if the user is actually an admin or not (example reporting)
Session::write('login_as', true);
$logInfo = [
'tool' => 'login',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => '',
'info' => $userId,
];
Event::registerLog($logInfo);
return true;
}
@ -5981,8 +6029,8 @@ SQL;
public static function loginDelete($userId)
{
$online_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
$userId = intval($userId);
$query = "DELETE FROM ".$online_table." WHERE login_user_id = $userId";
$userId = (int) $userId;
$query = "DELETE FROM $online_table WHERE login_user_id = $userId";
Database::query($query);
}

@ -1289,7 +1289,7 @@ class Rest extends WebService
if (!$course_code) {
$course_code = CourseManager::get_course_code_from_course_id($course_id);
}
if (CourseManager::subscribe_user($user_id, $course_code)) {
if (CourseManager::subscribeUser($user_id, $course_code)) {
return [true];
} else {
return [false];

@ -59,6 +59,7 @@ class learnpath
public $theme; // The current theme of the learning path.
public $preview_image; // The current image of the learning path.
public $accumulateScormTime; // Flag to decide whether to accumulate SCORM time or not
public $accumulateWorkTime; // The min time of learnpath
// Tells if all the items of the learnpath can be tried again. Defaults to "no" (=1).
public $prevent_reinit = 1;
@ -162,6 +163,7 @@ class learnpath
$this->ref = $row['ref'];
$this->categoryId = $row['category_id'];
$this->accumulateScormTime = isset($row['accumulate_scorm_time']) ? $row['accumulate_scorm_time'] : 'true';
$this->accumulateWorkTime = isset($row['accumulate_work_time']) ? $row['accumulate_work_time'] : 0;
if (!empty($row['publicated_on'])) {
$this->publicated_on = $row['publicated_on'];
@ -2331,12 +2333,18 @@ class learnpath
$courseInfo,
$sessionId
) {
if (empty($courseInfo)) {
return false;
}
$courseId = $courseInfo['real_id'];
$allow = api_get_configuration_value('allow_teachers_to_access_blocked_lp_by_prerequisite');
if ($allow) {
if (api_is_allowed_to_edit() ||
api_is_platform_admin(true) ||
api_is_drh() ||
api_is_coach($sessionId, $courseInfo['real_id'], false)
api_is_coach($sessionId, $courseId, false)
) {
return false;
}
@ -2348,12 +2356,49 @@ class learnpath
$progress = self::getProgress(
$prerequisite,
$studentId,
$courseInfo['real_id'],
$courseId,
$sessionId
);
if ($progress < 100) {
$isBlocked = true;
}
if (api_get_configuration_value('lp_minimum_time')) {
// Block if it does not exceed minimum time
// Minimum time (in minutes) to pass the learning path
$accumulateWorkTime = self::getAccumulateWorkTimePrerequisite($prerequisite, $courseId);
if ($accumulateWorkTime > 0) {
// Total time in course (sum of times in learning paths from course)
$accumulateWorkTimeTotal = self::getAccumulateWorkTimeTotal($courseId);
// Connect with the plugin_licences_course_session table
// which indicates what percentage of the time applies
// Minimum connection percentage
$perc = 100;
// Time from the course
$tc = $accumulateWorkTimeTotal;
// Percentage of the learning paths
$pl = $accumulateWorkTime / $accumulateWorkTimeTotal;
// Minimum time for each learning path
$accumulateWorkTime = ($pl * $tc * $perc / 100);
// Spent time (in seconds) so far in the learning path
/*$lpTime = Tracking::get_time_spent_in_lp(
$studentId,
$courseInfo['code'],
[$prerequisite],
$sessionId
);*/
$lpTimeList = Tracking::getCalculateTime($studentId, $courseId, $sessionId);
$lpTime = isset($lpTimeList[TOOL_LEARNPATH][$prerequisite]) ? $lpTimeList[TOOL_LEARNPATH][$prerequisite] : 0;
if ($lpTime < ($accumulateWorkTime * 60)) {
$isBlocked = true;
}
}
}
}
return $isBlocked;
@ -3609,11 +3654,9 @@ class learnpath
$item_id,
$this->get_view_id()
);
if ($this->debug > 0) {
error_log('rl_get_resource_link_for_learnpath - file: '.$file, 0);
}
switch ($lp_item_type) {
case 'document':
// Shows a button to download the file instead of just downloading the file directly.
@ -3622,7 +3665,18 @@ class learnpath
$parsed = parse_url($documentPathInfo['extension']);
if (isset($parsed['path'])) {
$extension = $parsed['path'];
$extensionsToDownload = ['zip', 'ppt', 'pptx', 'ods', 'xlsx', 'xls', 'csv'];
$extensionsToDownload = [
'zip',
'ppt',
'pptx',
'ods',
'xlsx',
'xls',
'csv',
'doc',
'docx',
'dot',
];
if (in_array($extension, $extensionsToDownload)) {
$file = api_get_path(WEB_CODE_PATH).
@ -7424,13 +7478,21 @@ class learnpath
}
break;
case TOOL_LINK:
$link_id = (string) $row['path'];
if (ctype_digit($link_id)) {
$tbl_link = Database::get_course_table(TABLE_LINK);
$sql_select = 'SELECT url FROM '.$tbl_link.'
WHERE c_id = '.$course_id.' AND iid = '.intval($link_id);
$res_link = Database::query($sql_select);
$linkId = (int) $row['path'];
if (!empty($linkId)) {
$table = Database::get_course_table(TABLE_LINK);
$sql = 'SELECT url FROM '.$table.'
WHERE c_id = '.$course_id.' AND iid = '.$linkId;
$res_link = Database::query($sql);
$row_link = Database::fetch_array($res_link);
if (empty($row_link)) {
// Try with id
$sql = 'SELECT url FROM '.$table.'
WHERE c_id = '.$course_id.' AND id = '.$linkId;
$res_link = Database::query($sql);
$row_link = Database::fetch_array($res_link);
}
if (is_array($row_link)) {
$row['url'] = $row_link['url'];
}
@ -10028,6 +10090,7 @@ class learnpath
if (in_array($item_type, [TOOL_DOCUMENT, TOOL_LP_FINAL_ITEM, TOOL_HOTPOTATOES])) {
$documentData = DocumentManager::get_document_data_by_id($row['path'], $course_code);
if (empty($documentData)) {
// Try with iid
$table = Database::get_course_table(TABLE_DOCUMENT);
$sql = "SELECT path FROM $table
WHERE
@ -13770,6 +13833,153 @@ EOD;
return true;
}
/**
* Get whether this is a learning path with the accumulated work time or not.
*
* @return int
*/
public function getAccumulateWorkTime()
{
return (int) $this->accumulateWorkTime;
}
/**
* Get whether this is a learning path with the accumulated work time or not.
*
* @return int
*/
public function getAccumulateWorkTimeTotalCourse()
{
$table = Database::get_course_table(TABLE_LP_MAIN);
$sql = "SELECT SUM(accumulate_work_time) AS total
FROM $table
WHERE c_id = ".$this->course_int_id;
$result = Database::query($sql);
$row = Database::fetch_array($result);
return (int) $row['total'];
}
/**
* Set whether this is a learning path with the accumulated work time or not.
*
* @param int $value (0 = false, 1 = true)
*
* @return bool
*/
public function setAccumulateWorkTime($value)
{
if (!api_get_configuration_value('lp_minimum_time')) {
return false;
}
$this->accumulateWorkTime = (int) $value;
$table = Database::get_course_table(TABLE_LP_MAIN);
$lp_id = $this->get_id();
$sql = "UPDATE $table SET accumulate_work_time = ".$this->accumulateWorkTime."
WHERE c_id = ".$this->course_int_id." AND id = $lp_id";
Database::query($sql);
return true;
}
/**
* @param int $lpId
* @param int $courseId
*
* @return mixed
*/
public static function getAccumulateWorkTimePrerequisite($lpId, $courseId)
{
$lpId = (int) $lpId;
$courseId = (int) $courseId;
$table = Database::get_course_table(TABLE_LP_MAIN);
$sql = "SELECT accumulate_work_time
FROM $table
WHERE c_id = $courseId AND id = $lpId";
$result = Database::query($sql);
$row = Database::fetch_array($result);
return $row['accumulate_work_time'];
}
/**
* @param int $courseId
*
* @return int
*/
public static function getAccumulateWorkTimeTotal($courseId)
{
$table = Database::get_course_table(TABLE_LP_MAIN);
$courseId = (int) $courseId;
$sql = "SELECT SUM(accumulate_work_time) AS total
FROM $table
WHERE c_id = $courseId";
$result = Database::query($sql);
$row = Database::fetch_array($result);
return (int) $row['total'];
}
/**
* In order to use the lp icon option you need to create the "lp_icon" LP extra field
* and put the images in.
*
* @return array
*/
public static function getIconSelect()
{
$theme = api_get_visual_theme();
$path = api_get_path(SYS_PUBLIC_PATH).'css/themes/'.$theme.'/lp_icons/';
$icons = ['' => get_lang('SelectAnOption')];
if (is_dir($path)) {
$finder = new Finder();
$finder->files()->in($path);
$allowedExtensions = ['jpeg', 'jpg', 'png'];
/** @var SplFileInfo $file */
foreach ($finder as $file) {
if (in_array(strtolower($file->getExtension()), $allowedExtensions)) {
$icons[$file->getFilename()] = $file->getFilename();
}
}
}
return $icons;
}
/**
* @param int $lpId
*
* @return string
*/
public static function getSelectedIcon($lpId)
{
$extraFieldValue = new ExtraFieldValue('lp');
$lpIcon = $extraFieldValue->get_values_by_handler_and_field_variable($lpId, 'lp_icon');
$icon = '';
if (!empty($lpIcon) && isset($lpIcon['value'])) {
$icon = $lpIcon['value'];
}
return $icon;
}
public static function getSelectedIconHtml($lpId)
{
$icon = self::getSelectedIcon($lpId);
if (empty($icon)) {
return '';
}
$theme = api_get_visual_theme();
$path = api_get_path(WEB_PUBLIC_PATH).'css/themes/'.$theme.'/lp_icons/'.$icon;
return Display::img($path);
}
/**
* Get the depth level of LP item.
*

@ -1889,14 +1889,62 @@ class learnpathItem
$sessionLifetime = 3600;
}
$fixedAddedMinute = 5 * 60; // Add only 5 minutes
if ($time > $sessionLifetime) {
error_log("fixAbusiveTime: Total time is too big: $time replaced with: $fixedAddedMinute");
error_log("item_id : ".$this->db_id." lp_item_view.iid: ".$this->db_item_view_id);
$time = $fixedAddedMinute;
}
if (!api_get_configuration_value('lp_minimum_time')) {
$fixedAddedMinute = 5 * 60; // Add only 5 minutes
if ($time > $sessionLifetime) {
error_log("fixAbusiveTime: Total time is too big: $time replaced with: $fixedAddedMinute");
error_log("item_id : ".$this->db_id." lp_item_view.iid: ".$this->db_item_view_id);
$time = $fixedAddedMinute;
}
return $time;
return $time;
} else {
// Calulate minimum and accumulated time
$user_id = api_get_user_id();
$myLP = learnpath::getLpFromSession(api_get_course_id(), $this->lp_id, $user_id);
$timeLp = $myLP->getAccumulateWorkTime();
$timeTotalCourse = $myLP->getAccumulateWorkTimeTotalCourse();
/*
$timeLp = $_SESSION['oLP']->getAccumulateWorkTime();
$timeTotalCourse = $_SESSION['oLP']->getAccumulateWorkTimeTotalCourse();
*/
// Minimum connection percentage
$perc = 100;
// Time from the course
$tc = $timeTotalCourse;
/*if (!empty($sessionId) && $sessionId != 0) {
$sql = "SELECT hours, perc FROM plugin_licences_course_session WHERE session_id = $sessionId";
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
$aux = Database::fetch_assoc($res);
$perc = $aux['perc'];
$tc = $aux['hours'] * 60;
}
}*/
// Percentage of the learning paths
$pl = 0;
if (!empty($timeTotalCourse)) {
$pl = $timeLp / $timeTotalCourse;
}
// Minimum time for each learning path
$accumulateWorkTime = ($pl * $tc * $perc / 100);
$time_seg = intval($accumulateWorkTime * 60);
if ($time_seg < $sessionLifetime) {
$sessionLifetime = $time_seg;
}
if ($time > $sessionLifetime) {
$fixedAddedMinute = $time_seg + mt_rand(0, 300);
if (self::DEBUG > 2) {
error_log("Total time is too big: $time replaced with: $fixedAddedMinute");
}
$time = $fixedAddedMinute;
}
return $time;
}
}
/**

@ -491,6 +491,15 @@ function save_item(
$return .= "update_stats();";
}
$logInfo = [
'tool' => TOOL_LEARNPATH,
'tool_id' => $myLP->get_id(),
'tool_id_detail' => $myLP->get_current_item_id(),
'action' => 'save_item',
'info' => '',
];
Event::registerLog($logInfo);
// To be sure progress is updated.
$myLP->save_last();

@ -217,10 +217,63 @@ function switch_item_details($lp_id, $user_id, $view_id, $current_item, $next_it
"olms.lms_item_core_exit = '".$mycore_exit."';".
"olms.asset_timer = 0;";
$return .= "update_toc('unhighlight','".$current_item."');".
$updateMinTime = '';
if (api_get_configuration_value('lp_minimum_time')) {
$timeLp = $mylp->getAccumulateWorkTime();
$timeTotalCourse = $mylp->getAccumulateWorkTimeTotalCourse();
// Minimum connection percentage
$perc = 100;
// Time from the course
$tc = $timeTotalCourse;
$sessionId = api_get_session_id();
if (!empty($sessionId) && $sessionId != 0) {
/*$sql = "SELECT hours, perc FROM plugin_licences_course_session WHERE session_id = $sessionId";
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
$aux = Database::fetch_assoc($res);
$perc = $aux['perc'];
$tc = $aux['hours'] * 60;
}*/
}
// Percentage of the learning paths
$pl = $timeLp / $timeTotalCourse;
// Minimum time for each learning path
$time_total = intval($pl * $tc * $perc / 100) * 60;
//$time_total = $mylp->getAccumulateWorkTime() * 60;
/*$lpTime = Tracking::get_time_spent_in_lp(
$user_id,
api_get_course_id(),
[$lp_id],
api_get_session_id()
);*/
$lpTimeList = Tracking::getCalculateTime($user_id, api_get_course_int_id(), api_get_session_id());
$lpTime = isset($lpTimeList[TOOL_LEARNPATH][$lp_id]) ? $lpTimeList[TOOL_LEARNPATH][$lp_id] : 0;
if ($lpTime >= $time_total) {
$time_spent = $time_total;
} else {
$time_spent = $lpTime;
}
$hour = (intval($lpTime / 3600)) < 10 ? '0'.intval($lpTime / 3600) : intval($lpTime / 3600);
$minute = date('i', $lpTime);
$second = date('s', $lpTime);
$updateMinTime = "update_time_bar('$time_spent','$time_total','%');".
"update_chronometer('$hour','$minute','$second');";
}
$return .=
"update_toc('unhighlight','".$current_item."');".
"update_toc('highlight','".$new_item_id."');".
"update_toc('$mylesson_status','".$new_item_id."');".
"update_progress_bar('$mycomplete','$mytotal','$myprogress_mode');";
"update_progress_bar('$mycomplete','$mytotal','$myprogress_mode');".
$updateMinTime
;
$return .= 'updateGamificationValues(); ';
$mylp->set_error_msg('');

@ -116,5 +116,5 @@ if ($debug > 0) {
error_log('New LP - In lp_content.php - Loading '.$src);
}
Session::write('oLP', $learnPath);
header("Location: ".urldecode($src));
header('Location: '.urldecode($src));
exit;

@ -263,13 +263,14 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
// Select the lp in the database and check which type it is (scorm/dokeos/aicc) to generate the
// right object.
if (!empty($_REQUEST['lp_id'])) {
$lp_id = intval($_REQUEST['lp_id']);
$lp_id = $_REQUEST['lp_id'];
} else {
$lp_id = intval($myrefresh_id);
$lp_id = $myrefresh_id;
}
$lp_id = (int) $lp_id;
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
if (is_numeric($lp_id)) {
if (!empty($lp_id)) {
$sel = "SELECT iid, lp_type FROM $lp_table WHERE c_id = $course_id AND id = $lp_id";
if ($debug > 0) {
error_log(' querying '.$sel);
@ -283,6 +284,14 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
error_log('Found row type '.$type);
error_log('Calling constructor: '.api_get_course_id().' - '.$lp_id.' - '.api_get_user_id());
}
$logInfo = [
'tool' => TOOL_LEARNPATH,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'lp_load',
];
Event::registerLog($logInfo);
switch ($type) {
case 1:
$oLP = new learnpath(api_get_course_id(), $lpIid, api_get_user_id());
@ -369,6 +378,36 @@ if ($debug) {
error_log('Entered lp_controller.php -+- (action: '.$action.')');
}
$eventLpId = $lp_id = !empty($_REQUEST['lp_id']) ? (int) $_REQUEST['lp_id'] : 0;
if (empty($lp_id)) {
if (isset($_SESSION['oLP'])) {
$eventLpId = $_SESSION['oLP']->get_id();
}
}
$lp_detail_id = 0;
switch ($action) {
case '':
case 'list':
$eventLpId = 0;
break;
case 'view':
case 'content':
$lp_detail_id = $_SESSION['oLP']->get_current_item_id();
break;
default:
$lp_detail_id = (!empty($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0);
break;
}
$logInfo = [
'tool' => TOOL_LEARNPATH,
'tool_id' => $eventLpId,
'tool_id_detail' => $lp_detail_id,
'action' => !empty($action) ? $action : 'list',
];
Event::registerLog($logInfo);
// format title to be displayed correctly if QUIZ
$post_title = '';
if (isset($_POST['title'])) {
@ -392,6 +431,54 @@ if ($debug > 0) {
}
switch ($action) {
case 'send_notify_teacher':
// Enviar correo al profesor
$studentInfo = api_get_user_info();
$course_info = api_get_course_info();
global $_configuration;
$root_web = $_configuration['root_web'];
if (api_get_session_id() > 0) {
$session_info = api_get_session_info(api_get_session_id());
$course_name = $session_info['name'];
$course_url = $root_web.'courses/'.$course_info['code'].'/index.php?id_session='.api_get_session_id();
} else {
$course_name = $course_info['title'];
$course_url = $root_web.'courses/'.$course_info['code'].'/index.php?';
}
$url = Display::url($course_name, $course_url, ['title' => get_lang('GoToCourse')]);
$coachList = CourseManager::get_coachs_from_course(api_get_session_id(), api_get_course_int_id());
foreach ($coachList as $coach_course) {
$recipient_name = $coach_course['full_name'];
$coachInfo = api_get_user_info($coach_course['user_id']);
$email = $coachInfo['email'];
$tplContent = new Template(null, false, false, false, false, false);
// variables for the default template
$tplContent->assign('name_teacher', $recipient_name);
$tplContent->assign('name_student', $studentInfo['complete_name']);
$tplContent->assign('course_name', $course_name);
$tplContent->assign('course_url', $url);
//$tplContent->assign('telefono', $telefono);
//$tplContent->assign('prefix', $prefix);
$layoutContent = $tplContent->get_template('mail/content_ending_learnpath.tpl');
$emailBody = $tplContent->fetch($layoutContent);
api_mail_html(
$recipient_name,
$email,
sprintf(get_lang('StudentXFinishedLp'), $studentInfo['complete_name']),
$emailBody,
$studentInfo['complete_name'],
$studentInfo['email'],
true
);
}
Display::addFlash(Display::return_message(get_lang('MessageSent')));
require 'lp_list.php';
break;
case 'add_item':
if (!$is_allowed_to_edit) {
api_not_allowed(true);
@ -1030,12 +1117,9 @@ switch ($action) {
$hide_toc_frame = null;
}
$_SESSION['oLP']->set_hide_toc_frame($hide_toc_frame);
$_SESSION['oLP']->set_prerequisite(
isset($_POST['prerequisites']) ? (int) $_POST['prerequisites'] : 0
);
$_SESSION['oLP']->set_use_max_score(
isset($_POST['use_max_score']) ? 1 : 0
);
$_SESSION['oLP']->set_prerequisite(isset($_POST['prerequisites']) ? (int) $_POST['prerequisites'] : 0);
$_SESSION['oLP']->setAccumulateWorkTime(isset($_REQUEST['accumulate_work_time']) ? $_REQUEST['accumulate_work_time'] : 0);
$_SESSION['oLP']->set_use_max_score(isset($_POST['use_max_score']) ? 1 : 0);
$subscribeUsers = isset($_REQUEST['subscribe_users']) ? 1 : 0;
$_SESSION['oLP']->setSubscribeUsers($subscribeUsers);
@ -1064,9 +1148,7 @@ switch ($action) {
}
$extraFieldValue = new ExtraFieldValue('lp');
$params = [
'lp_id' => $_SESSION['oLP']->lp_id,
];
$_REQUEST['item_id'] = $_SESSION['oLP']->lp_id;
$extraFieldValue->saveFieldValues($_REQUEST);
if ($_FILES['lp_preview_image']['size'] > 0) {

@ -159,6 +159,14 @@ $form->addElement('html', '</div>');
$form->addElement('html', '<div class="col-md-2"></div>');
$form->addElement('html', '</div>');
//Start date
// Time Control
if (api_get_configuration_value('lp_minimum_time')) {
$accumulateTime = $_SESSION['oLP']->getAccumulateWorkTime();
$form->addText('accumulate_work_time', [get_lang('LpMinTime'), get_lang('LpMinTimeDescription')]);
$defaults['accumulate_work_time'] = $accumulateTime;
}
// Start date
$form->addElement(
'checkbox',
'activate_start_date_check',
@ -218,6 +226,17 @@ $form->addElement(
get_lang('AccumulateScormTime')
);
$options = learnpath::getIconSelect();
if (!empty($options)) {
$form->addSelect(
'extra_lp_icon',
get_lang('Icon'),
$options
);
$defaults['extra_lp_icon'] = learnpath::getSelectedIcon($lpId);
}
$enableLpExtraFields = false;
if ($enableLpExtraFields) {
$extraField = new ExtraField('lp');

@ -73,22 +73,6 @@ $message = '';
$actions = '';
if ($is_allowed_to_edit) {
if (!empty($dialog_box)) {
switch ($_GET['dialogtype']) {
case 'confirmation':
$message = Display::return_message($dialog_box, 'success');
break;
case 'error':
$message = Display::return_message($dialog_box, 'danger');
break;
case 'warning':
$message = Display::return_message($dialog_box, 'warning');
break;
default:
$message = Display::return_message($dialog_box);
break;
}
}
$actionLeft = '';
$actionLeft .= Display::url(
Display::return_icon(
@ -169,7 +153,11 @@ if ($filteredCategoryId) {
}
$test_mode = api_get_setting('server_type');
$showBlockedPrerequisite = api_get_configuration_value('show_prerequisite_as_blocked');
$allowLpChamiloExport = api_get_configuration_value('allow_lp_chamilo_export');
$allowMinTime = api_get_configuration_value('lp_minimum_time');
$user = api_get_user_entity($userId);
$ending = true;
$data = [];
/** @var CLpCategory $item */
@ -215,12 +203,24 @@ foreach ($categories as $item) {
$showBlockedPrerequisite = api_get_configuration_value('show_prerequisite_as_blocked');
$allowLpChamiloExport = api_get_configuration_value('allow_lp_chamilo_export');
$listData = [];
$lpTimeList = [];
if ($allowMinTime) {
$lpTimeList = Tracking::getCalculateTime($userId, api_get_course_int_id(), api_get_session_id());
}
$options = learnpath::getIconSelect();
if (!empty($flat_list)) {
$max = count($flat_list);
$counter = 0;
$current = 0;
$autolaunch_exists = false;
$accumulateWorkTimeTotal = 0;
if ($allowMinTime) {
// TT --- Tiempo total del curso
$accumulateWorkTimeTotal = learnpath::getAccumulateWorkTimeTotal(api_get_course_int_id());
}
foreach ($flat_list as $id => $details) {
$id = $details['lp_old_id'];
// Validation when belongs to a session.
@ -347,6 +347,13 @@ foreach ($categories as $item) {
);
}
if (!empty($options)) {
$icon = learnpath::getSelectedIconHtml($id);
if (!empty($icon)) {
$icon_learnpath = $icon;
}
}
// Students can see the lp but is inactive
if (!$is_allowed_to_edit && $lpVisibility == false &&
$showBlockedPrerequisite == true
@ -392,6 +399,65 @@ foreach ($categories as $item) {
}
}
if ($progress < 100) {
$ending = false;
}
$dsp_time = '';
$linkMinTime = '';
if ($allowMinTime) {
// Time info
// Minimum time (in minutes) to pass the learning path
$accumulateWorkTime = learnpath::getAccumulateWorkTimePrerequisite($id, api_get_course_int_id());
if ($accumulateWorkTime > 0) {
$lpTime = isset($lpTimeList[TOOL_LEARNPATH][$id]) ? $lpTimeList[TOOL_LEARNPATH][$id] : 0;
// Connect with the plugin_licences_course_session table
// which indicates what percentage of the time applies
$perc = 100;
// Percentage of the learning paths
$pl = 0;
if (!empty($accumulateWorkTimeTotal)) {
$pl = $accumulateWorkTime / $accumulateWorkTimeTotal;
}
// Minimum time for each learning path
$accumulateWorkTime = ($pl * $accumulateWorkTimeTotal * $perc / 100);
// If the time spent is less than necessary, then we show an icon in the actions column indicating the warning
if ($lpTime < ($accumulateWorkTime * 60)) {
$linkMinTime = Display::return_icon(
'warning.png',
get_lang('LpMinTimeWarning').' - '.api_time_to_hms($lpTime).' / '.api_time_to_hms(
$accumulateWorkTime * 60
)
);
} else {
$linkMinTime = Display::return_icon(
'check.png',
get_lang('LpMinTimeWarning').' - '.api_time_to_hms($lpTime).' / '.api_time_to_hms(
$accumulateWorkTime * 60
)
);
}
$linkMinTime .= '&nbsp;<b>'.api_time_to_hms($lpTime).' / '.api_time_to_hms($accumulateWorkTime * 60).'</b>';
// Calculate the percentage exceeded of the time for the "exceeding the minimum time" bar
if ($lpTime >= ($accumulateWorkTime * 60)) {
$time_progress_perc = '100%';
$time_progress_value = 100;
} else {
$time_progress_value = intval(($lpTime * 100) / ($accumulateWorkTime * 60));
}
if ($time_progress_value < 100) {
$ending = false;
}
$dsp_time = learnpath::get_progress_bar($time_progress_value, '%');
}
}
$token_parameter = "&sec_token=$token";
$dsp_edit_lp = null;
$dsp_publish = null;
@ -893,6 +959,7 @@ foreach ($categories as $item) {
'action_subscribe_users' => $subscribeUsers,
'action_update_scorm' => $actionUpdateScormFile,
'action_export_to_course_build' => $actionExportToCourseBuild,
'info_time_prerequisite' => $linkMinTime,
];
$lpIsShown = true;
@ -933,6 +1000,7 @@ $template = new Template($nameTools);
$template->assign('subscription_settings', $subscriptionSettings);
$template->assign('is_allowed_to_edit', $is_allowed_to_edit);
$template->assign('is_invitee', api_is_invitee());
$template->assign('is_ending', $ending);
$template->assign('actions', $actions);
$template->assign('categories', $categories);
$template->assign('message', $message);
@ -940,5 +1008,6 @@ $template->assign('introduction', $introduction);
$template->assign('data', $data);
$template->assign('lp_is_shown', $lpIsShown);
$template->assign('filtered_category', $filteredCategoryId);
$template->assign('allow_min_time', $allowMinTime);
$template->displayTemplate('@ChamiloTheme/LearnPath/list.html.twig');

@ -542,6 +542,52 @@ if ($gamificationMode == 1) {
}
$template->assign('lp_author', $lp->get_author());
$lpMinTime = '';
if (api_get_configuration_value('lp_minimum_time')) {
// Calulate minimum and accumulated time
$timeLp = $_SESSION['oLP']->getAccumulateWorkTime();
$timeTotalCourse = $_SESSION['oLP']->getAccumulateWorkTimeTotalCourse();
// Minimum connection percentage
$perc = 100;
// Time from the course
$tc = $timeTotalCourse;
// Percentage of the learning paths
$pl = 0;
if (!empty($timeTotalCourse)) {
$pl = $timeLp / $timeTotalCourse;
}
// Minimum time for each learning path
$time_min = intval($pl * $tc * $perc / 100);
if ($_SESSION['oLP']->getAccumulateWorkTime() > 0) {
$lpMinTime = '('.$time_min.' min)';
}
$lpTimeList = Tracking::getCalculateTime($user_id, api_get_course_int_id(), api_get_session_id());
$lpTime = isset($lpTimeList[TOOL_LEARNPATH][$lp_id]) ? (int) $lpTimeList[TOOL_LEARNPATH][$lp_id] : 0;
if ($lpTime >= ($time_min * 60)) {
$time_progress_perc = '100%';
$time_progress_value = 100;
} else {
$time_progress_value = intval(($lpTime * 100) / ($time_min * 60));
$time_progress_perc = $time_progress_value.'%';
}
$template->assign('time_progress_perc', $time_progress_perc);
$template->assign('time_progress_value', $time_progress_value);
// Cronometro
$hour = (intval($lpTime / 3600)) < 10 ? '0'.intval($lpTime / 3600) : intval($lpTime / 3600);
$template->assign('hour', $hour);
$template->assign('minute', date('i', $lpTime));
$template->assign('second', date('s', $lpTime));
$template->assign('hour_min', api_time_to_hms($timeLp * 60, '</div><div class="divider">:</div><div>'));
}
$template->assign('lp_accumulate_work_time', $lpMinTime);
$template->assign('lp_mode', $lp->mode);
$template->assign('lp_title_scorm', $lp->name);
if (api_get_configuration_value('lp_view_accordion') === true && $lpType == 1) {
@ -561,6 +607,9 @@ $template->assign(
ICON_SIZE_BIG
)
);
$frameReady = Display::getFrameReadyBlock('top.content_name');
$template->assign('frame_ready', $frameReady);
$template->displayTemplate('@ChamiloTheme/LearnPath/view.html.twig');
// Restore a global setting.

@ -2383,3 +2383,95 @@ function attach_glossary_into_scorm(type) {
}
}
}
/**
* Updates the time bar with the new status. Prevents the need of a page refresh and flickering
* @param integer Number of completed items
* @param integer Number of items in total
* @param string Display mode (absolute 'abs' or percentage '%').Defaults to %
*/
function update_time_bar(nbr_complete, nbr_total, mode)
{
logit_lms('update_progress_bar('+nbr_complete+', '+nbr_total+', '+mode+')',3);
logit_lms(
'update_progress_bar with params: lms_lp_id= ' + olms.lms_lp_id +
', lms_view_id= '+ olms.lms_view_id + ' lms_user_id= '+ olms.lms_user_id,
3
);
if (mode == '') {
mode='%';
}
if (nbr_total == 0) {
nbr_total=1;
}
var percentage = (nbr_complete/nbr_total)*100;
percentage = Math.round(percentage);
var progress_bar = $("#progress_bar_value2");
progress_bar.css('width', percentage + "%");
var mytext = '';
switch(mode){
case 'abs':
mytext = nbr_complete + '/' + nbr_total;
break;
case '%':
default:
mytext = percentage + '%';
break;
}
progress_bar.html(mytext);
return true;
}
/**
* Update chronometer
*/
function update_chronometer(text_hour, text_minute, text_second)
{
$("#hour").text(text_hour);
$("#minute").text(text_minute);
$("#second").text(text_second);
var timerData = {
hour: parseInt($("#hour").text()),
minute: parseInt($("#minute").text()),
second: parseInt($("#second").text())
};
/*
var timerData = {
hour: text_hour,
minute: text_minute,
second: text_second
};
*/
//window.timerInterval = null;
clearInterval(window.timerInterval);
window.timerInterval = setInterval(function(){
// Seconds
timerData.second++;
if(timerData.second >= 60) {
timerData.second = 0;
timerData.minute++;
}
// Minutes
if(timerData.minute >= 60) {
timerData.minute = 0;
timerData.hour++;
}
$("#hour").text(timerData.hour < 10 ? '0' + timerData.hour : timerData.hour);
//$("#hour").text(timerData.hour);
$("#minute").text(timerData.minute < 10 ? '0' + timerData.minute : timerData.minute);
//$("#minute").text(timerData.minute);
$("#second").text(timerData.second < 10 ? '0' + timerData.second : timerData.second);
//$("#second").text(timerData.second);
}, 1000);
return true;
}

@ -14,6 +14,17 @@ if (api_get_setting('allow_message_tool') != 'true') {
api_not_allowed(true);
}
$logInfo = [
'tool' => 'Messages',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => isset($_GET['action']) ? $_GET['action'] : 'inbox',
'action_details' => '',
'current_id' => isset($_GET['id']) ? (int) $_GET['id'] : 0,
'info' => '',
];
Event::registerLog($logInfo);
$allowSocial = api_get_setting('allow_social_tool') == 'true';
$allowMessage = api_get_setting('allow_message_tool') == 'true';

@ -22,6 +22,17 @@ if (api_get_setting('allow_message_tool') !== 'true') {
api_not_allowed(true);
}
$logInfo = [
'tool' => 'Messages',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => 'new_message',
'action_details' => isset($_GET['re_id']) ? 're_id' : '',
'current_id' => isset($_GET['re_id']) ? (int) $_GET['re_id'] : 0,
'info' => '',
];
Event::registerLog($logInfo);
$allowSocial = api_get_setting('allow_social_tool') == 'true';
$nameTools = api_xml_http_response_encode(get_lang('Messages'));
@ -49,10 +60,9 @@ function add_image_form() {
}
}
</script>';
$nameTools = get_lang('ComposeMessage');
$tpl = new Template($nameTools);
$tpl = new Template(get_lang('ComposeMessage'));
/**
* Shows the compose area + a list of users to select from.

@ -13,6 +13,17 @@ if (api_get_setting('allow_message_tool') != 'true') {
api_not_allowed(true);
}
$logInfo = [
'tool' => 'Messages',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => isset($_GET['action']) ? $_GET['action'] : 'outbox',
'action_details' => '',
'current_id' => isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0,
'info' => '',
];
Event::registerLog($logInfo);
$allowSocial = api_get_setting('allow_social_tool') == 'true';
$allowMessage = api_get_setting('allow_message_tool') == 'true';
$show_message = null;

@ -50,6 +50,17 @@ if (empty($_GET['id'])) {
$show_menu = 'messages_inbox';
}
$logInfo = [
'tool' => 'Messages',
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $source,
'action_details' => 'view-message',
'current_id' => $messageId,
'info' => '',
];
Event::registerLog($logInfo);
// MAIN CONTENT
$message_content = MessageManager::showMessageBox($messageId, $source);

@ -36,6 +36,17 @@ $skipData = api_get_configuration_value('tracking_skip_generic_data');
// Access control
api_block_anonymous_users();
$logInfo = [
'tool' => SECTION_TRACKING,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => '',
'action_details' => '',
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
$allowToTrack = api_is_platform_admin(true, true) || api_is_teacher();
if (!$allowToTrack) {

@ -212,6 +212,235 @@ $user_id = isset($_GET['user_id']) && !empty($_GET['user_id']) ? (int) $_GET['us
$action = isset($_GET['action']) ? $_GET['action'] : '';
switch ($action) {
case 'export_to_pdf':
$sessionToExport = $sId = isset($_GET['session_to_export']) ? (int) $_GET['session_to_export'] : 0;
$sessionInfo = api_get_session_info($sessionToExport);
if (empty($sessionInfo)) {
api_not_allowed(true);
}
$courses = Tracking::get_courses_list_from_session($sessionToExport);
$timeSpent = 0;
$numberVisits = 0;
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
$progress = 0;
foreach ($courses as $course) {
$courseId = $course['c_id'];
$timeSpent += Tracking::get_time_spent_on_the_course($student_id, $courseId, $sessionToExport);
$sql = 'SELECT DISTINCT count(course_access_id) as count
FROM '.$table.'
WHERE
user_id = '.$student_id.' AND
c_id = '.$courseId.' AND
session_id = '.$sessionToExport.'
ORDER BY login_course_date ASC';
$result = Database::query($sql);
$row = Database::fetch_array($result);
$numberVisits += $row['count'];
$progress += Tracking::get_avg_student_progress($student_id, $course['code'], [], $sessionToExport);
}
$average = round($progress / count($courses), 1);
$average = empty($average) ? '0%' : $average.'%';
$first = Tracking::get_first_connection_date($student_id);
$last = Tracking::get_last_connection_date($student_id);
$attendance = new Attendance();
$table = new HTML_Table(['class' => 'data_table']);
$column = 0;
$row = 0;
$headers = [
get_lang('TimeSpent'),
get_lang('NumberOfVisits'),
get_lang('GlobalProgress'),
get_lang('FirstLogin'),
get_lang('LastConnexionDate'),
];
foreach ($headers as $header) {
$table->setHeaderContents($row, $column, $header);
$column++;
}
$table->setCellContents(1, 0, api_time_to_hms($timeSpent));
$table->setCellContents(1, 1, $numberVisits);
$table->setCellContents(1, 2, $average);
$table->setCellContents(1, 3, $first);
$table->setCellContents(1, 4, $last);
$courseTable = '';
if (!empty($courses)) {
$courseTable .= '<table class="data_table">';
$courseTable .= '<thead>';
$courseTable .= '<tr>
<th>'.get_lang('FormationUnit').'</th>
<th>'.get_lang('ConnectionTime').'</th>
<th>'.get_lang('Progress').'</th>
<th>'.get_lang('Score').'</th>
</tr>';
$courseTable .= '</thead>';
$courseTable .= '<tbody>';
$totalCourseTime = 0;
$totalAttendance = [0, 0];
$totalScore = 0;
$totalProgress = 0;
$gradeBookTotal = [0, 0];
$totalEvaluations = '0/0 (0%)';
$totalCourses = count($courses);
$scoreDisplay = ScoreDisplay::instance();
foreach ($courses as $course) {
$courseId = $course['c_id'];
$courseInfoItem = api_get_course_info_by_id($courseId);
$courseId = $courseInfoItem['real_id'];
$courseCodeItem = $courseInfoItem['code'];
$isSubscribed = CourseManager::is_user_subscribed_in_course(
$student_id,
$courseCodeItem,
true,
$sId
);
if ($isSubscribed) {
$timeInSeconds = Tracking::get_time_spent_on_the_course(
$user_info['user_id'],
$courseId,
$sessionToExport
);
$totalCourseTime += $timeInSeconds;
$time_spent_on_course = api_time_to_hms($timeInSeconds);
$progress = Tracking::get_avg_student_progress(
$user_info['user_id'],
$courseCodeItem,
[],
$sId
);
$totalProgress += $progress;
$bestScore = Tracking::get_avg_student_score(
$user_info['user_id'],
$courseCodeItem,
[],
$sId,
false,
false,
true
);
if (is_numeric($bestScore)) {
$totalScore += $bestScore;
}
/*$score = Tracking::get_avg_student_score(
$user_info['user_id'],
$courseCodeItem,
[],
$sId
);*/
$progress = empty($progress) ? '0%' : $progress.'%';
$score = empty($bestScore) ? '0%' : $bestScore.'%';
$courseTable .= '<tr>
<td ><a href="'.$courseInfoItem['course_public_url'].'?id_session='.$sId.'">'.
$courseInfoItem['title'].'</a></td>
<td >'.$time_spent_on_course.'</td>
<td >'.$progress.'</td>
<td >'.$score.'</td>';
$courseTable .= '</tr>';
}
}
$totalAttendanceFormatted = $scoreDisplay->display_score($totalAttendance);
$totalScoreFormatted = $scoreDisplay->display_score([$totalScore / $totalCourses, 100], SCORE_AVERAGE);
$totalProgressFormatted = $scoreDisplay->display_score(
[$totalProgress / $totalCourses, 100],
SCORE_AVERAGE
);
$totalEvaluations = $scoreDisplay->display_score($gradeBookTotal);
$totalTimeFormatted = api_time_to_hms($totalCourseTime);
$courseTable .= '
<tr>
<th>'.get_lang('Total').'</th>
<th>'.$totalTimeFormatted.'</th>
<th>'.$totalProgressFormatted.'</th>
<th>'.$totalScoreFormatted.'</th>
</tr>';
$courseTable .= '</tbody></table>';
}
$studentInfo = api_get_user_info($student_id);
$tpl = new Template('', false, false, false, true, false, false);
$tpl->assign('title', get_lang('AttestationOfAttendance'));
$tpl->assign('session_title', $sessionInfo['name']);
$tpl->assign('student', $studentInfo['complete_name']);
$tpl->assign('table_progress', $table->toHtml());
$tpl->assign('subtitle', sprintf(
get_lang('InSessionXYouHadTheFollowingResults'),
$sessionInfo['name']
));
$tpl->assign('table_course', $courseTable);
$template = $tpl->fetch($tpl->get_template('my_space/pdf_export_student.tpl'));
$content = ''.$template;
$params = [
'pdf_title' => get_lang('Resume'),
//'course_code' => api_get_course_id(),
'session_info' => $sessionInfo,
'course_info' => '',
'pdf_date' => '',
'student_info' => $studentInfo,
'show_grade_generated_date' => true,
'show_real_course_teachers' => false,
'show_teacher_as_myself' => false,
'orientation' => 'P',
];
$pdf = new PDF('A4', $params['orientation'], $params);
try {
$theme = $tpl->theme;
$themeName = empty($theme) ? api_get_visual_theme() : $theme;
$themeDir = \Template::getThemeDir($theme);
$customLetterhead = $themeDir.'images/letterhead.png';
$urlPathLetterhead = api_get_path(SYS_CSS_PATH).$customLetterhead;
$urlWebLetterhead = '#FFFFFF';
$fullPage = false;
if (file_exists($urlPathLetterhead)) {
$fullPage = true;
$urlWebLetterhead = 'url('.api_get_path(WEB_CSS_PATH).$customLetterhead.')';
}
if ($fullPage) {
$pdf->pdf->SetDisplayMode('fullpage');
$pdf->pdf->SetDefaultBodyCSS('background', $urlWebLetterhead);
$pdf->pdf->SetDefaultBodyCSS('background-image-resize', '6');
}
@$pdf->content_to_pdf($content,
$css = '',
$pdf_name = '',
$course_code = null,
$outputMode = 'D',
$saveInFile = false,
$fileToSave = null,
$returnHtml = false,
$addDefaultCss = true,
$completeHeader = false
);
} catch (MpdfException $e) {
error_log($e);
}
exit;
break;
case 'export_one_session_row':
$sessionToExport = isset($_GET['session_to_export']) ? (int) $_GET['session_to_export'] : 0;
$exportList = Session::read('export_course_list');
@ -386,7 +615,7 @@ $sql = "SELECT c_id
FROM $tbl_course_user
WHERE
relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND
user_id = ".intval($user_info['user_id']);
user_id = ".$student_id;
$rs = Database::query($sql);
while ($row = Database::fetch_array($rs)) {
@ -402,7 +631,7 @@ while ($row = Database::fetch_array($rs)) {
// Get the list of sessions where the user is subscribed as student
$sql = 'SELECT session_id, c_id
FROM '.Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER).'
WHERE user_id='.intval($user_info['user_id']);
WHERE user_id='.$student_id;
$rs = Database::query($sql);
$tmp_sessions = [];
while ($row = Database::fetch_array($rs, 'ASSOC')) {
@ -1107,6 +1336,17 @@ if (empty($details)) {
['action' => 'export_one_session_row', 'export' => 'xls', 'session_to_export' => $sId]
)
);
if (!empty($sId)) {
$sessionAction .= Display::url(
Display::return_icon('pdf.png', get_lang('ExportToPDF'), [], ICON_SIZE_MEDIUM),
$currentUrl
.'&'
.http_build_query(
['action' => 'export_to_pdf', 'session_to_export' => $sId]
)
);
}
echo $sessionAction;
} else {
echo "<tr><td colspan='5'>".get_lang('NoCourse')."</td></tr>";
@ -1147,6 +1387,11 @@ if (empty($details)) {
),
];
$timeCourse = null;
if (api_get_configuration_value('lp_minimum_time')) {
$timeCourse = Tracking::getCalculateTime($student_id, $courseInfo['real_id'], $session_id);
}
if ($user_info['status'] != INVITEE) {
$csv_content[] = [];
$csv_content[] = [str_replace('&nbsp;', '', strip_tags($table_title))];
@ -1173,265 +1418,238 @@ if (empty($details)) {
}
$csv_content[] = $columnHeadersToExport;
$columnHeadersKeys = array_keys($columnHeaders);
$categoriesTempList = learnpath::getCategories($courseInfo['real_id']);
$categoryTest = new CLpCategory();
$categoryTest->setId(0);
$categoryTest->setName(get_lang('WithOutCategory'));
$categoryTest->setPosition(0);
$categories = [
$categoryTest,
];
/*// @todo use LearnpathList class
if (empty($sessionId)) {
$dql = '
SELECT lp FROM ChamiloCourseBundle:CLp lp
WHERE
(lp.sessionId = 0 OR lp.sessionId IS NULL) AND
lp.cId = :course
ORDER BY lp.displayOrder ASC
';
$query = $em->createQuery($dql);
$query->setParameters([
'course' => $courseInfo['real_id']
]);
} else {
$dql = '
SELECT lp FROM ChamiloCourseBundle:CLp lp
WHERE
(lp.sessionId = :session OR lp.sessionId = 0 OR lp.sessionId IS NULL) AND
lp.cId = :course
ORDER BY lp.displayOrder ASC
';
$query = $em->createQuery($dql);
$query->setParameters([
'session' => $sessionId,
'course' => $courseInfo['real_id']
]);
if (!empty($categoriesTempList)) {
$categories = array_merge($categories, $categoriesTempList);
}
$lps = $query->getResult();
*/
if (true) {
$categoriesTempList = learnpath::getCategories($courseInfo['real_id']);
$categoryTest = new CLpCategory();
$categoryTest->setId(0);
$categoryTest->setName(get_lang('WithOutCategory'));
$categoryTest->setPosition(0);
$categories = [
$categoryTest,
];
if (!empty($categoriesTempList)) {
$categories = array_merge($categories, $categoriesTempList);
$userEntity = api_get_user_entity(api_get_user_id());
/** @var CLpCategory $item */
foreach ($categories as $item) {
$categoryId = $item->getId();
if (!learnpath::categoryIsVisibleForStudent($item, $userEntity)) {
continue;
}
$userEntity = api_get_user_entity(api_get_user_id());
$list = new LearnpathList(
api_get_user_id(),
$courseInfo['code'],
$sessionId,
null,
false,
$categoryId,
false,
true
);
/** @var CLpCategory $item */
foreach ($categories as $item) {
$categoryId = $item->getId();
if (!learnpath::categoryIsVisibleForStudent($item, $userEntity)) {
continue;
}
$flat_list = $list->get_flat_list();
$i = 0;
if (count($categories) > 1) {
echo Display::page_subheader2($item->getName());
}
$list = new LearnpathList(
api_get_user_id(),
$courseInfo['code'],
$sessionId,
null,
false,
$categoryId,
false,
true
);
echo '<div class="table-responsive">';
echo '<table class="table table-striped table-hover"><thead><tr>';
echo $headers;
echo '<th>'.get_lang('Details').'</th>';
if (api_is_allowed_to_edit()) {
echo '<th>'.get_lang('ResetLP').'</th>';
}
echo '</tr></thead><tbody>';
$flat_list = $list->get_flat_list();
$i = 0;
if (count($categories) > 1) {
echo Display::page_subheader2($item->getName());
}
foreach ($flat_list as $learnpath) {
$lpIdList[] = $learnpath['iid'];
echo '<div class="table-responsive">';
echo '<table class="table table-striped table-hover"><thead><tr>';
echo $headers;
echo '<th>'.get_lang('Details').'</th>';
if (api_is_allowed_to_edit()) {
echo '<th>'.get_lang('ResetLP').'</th>';
}
echo '</tr></thead><tbody>';
$lp_id = $learnpath['lp_old_id'];
$lp_name = $learnpath['lp_name'];
$any_result = false;
foreach ($flat_list as $learnpath) {
$lpIdList[] = $learnpath['iid'];
// Get progress in lp
$progress = Tracking::get_avg_student_progress(
$student_id,
$course_code,
[$lp_id],
$sessionId
);
$lp_id = $learnpath['lp_old_id'];
$lp_name = $learnpath['lp_name'];
$any_result = false;
if ($progress === null) {
$progress = '0%';
} else {
$any_result = true;
}
// Get progress in lp
$progress = Tracking::get_avg_student_progress(
// Get time in lp
if (!empty($timeCourse)) {
$lpTime = isset($timeCourse[TOOL_LEARNPATH]) ? $timeCourse[TOOL_LEARNPATH] : 0;
$total_time = isset($lpTime[$lp_id]) ? (int) $lpTime[$lp_id] : 0;
} else {
$total_time = Tracking::get_time_spent_in_lp(
$student_id,
$course_code,
[$lp_id],
$sessionId
);
}
if ($progress === null) {
$progress = '0%';
} else {
$any_result = true;
}
if (!empty($total_time)) {
$any_result = true;
}
// Get time in lp
$total_time = Tracking::get_time_spent_in_lp(
$student_id,
$course_code,
[$lp_id],
$sessionId
);
// Get last connection time in lp
$start_time = Tracking::get_last_connection_time_in_lp(
$student_id,
$course_code,
$lp_id,
$sessionId
);
if (!empty($total_time)) {
$any_result = true;
}
if (!empty($start_time)) {
$start_time = api_convert_and_format_date($start_time, DATE_TIME_FORMAT_LONG);
} else {
$start_time = '-';
}
// Get last connection time in lp
$start_time = Tracking::get_last_connection_time_in_lp(
$student_id,
$course_code,
$lp_id,
$sessionId
);
if (!empty($total_time)) {
$any_result = true;
}
if (!empty($start_time)) {
$start_time = api_convert_and_format_date($start_time, DATE_TIME_FORMAT_LONG);
} else {
$start_time = '-';
}
// Quiz in lp
$score = Tracking::get_avg_student_score(
$student_id,
$course_code,
[$lp_id],
$sessionId
);
if (!empty($total_time)) {
$any_result = true;
}
// Latest exercise results in a LP
$score_latest = Tracking::get_avg_student_score(
$student_id,
$course_code,
[$lp_id],
$sessionId,
false,
true
);
// Quiz in lp
$score = Tracking::get_avg_student_score(
$student_id,
$course_code,
[$lp_id],
$sessionId
);
$bestScore = Tracking::get_avg_student_score(
$student_id,
$course_code,
[$lp_id],
$sessionId,
false,
false,
true
);
// Latest exercise results in a LP
$score_latest = Tracking::get_avg_student_score(
$student_id,
$course_code,
[$lp_id],
$sessionId,
false,
true
);
if (empty($bestScore)) {
$bestScore = '';
} else {
$bestScore = $bestScore.'%';
}
$bestScore = Tracking::get_avg_student_score(
$student_id,
$course_code,
[$lp_id],
$sessionId,
false,
false,
true
);
if ($i % 2 == 0) {
$css_class = "row_even";
} else {
$css_class = "row_odd";
}
if (empty($bestScore)) {
$bestScore = '';
} else {
$bestScore = $bestScore.'%';
}
$i++;
if ($i % 2 == 0) {
$css_class = "row_even";
} else {
$css_class = "row_odd";
if (isset($score_latest) && !is_null($score_latest)) {
if (is_numeric($score_latest)) {
$score_latest = $score_latest.'%';
}
}
$i++;
if (is_numeric($progress)) {
$progress = $progress.'%';
} else {
$progress = '-';
}
if (isset($score_latest) && !is_null($score_latest)) {
if (is_numeric($score_latest)) {
$score_latest = $score_latest.'%';
}
}
echo '<tr class="'.$css_class.'">';
$contentToExport = [];
if (in_array('lp', $columnHeadersKeys)) {
$contentToExport[] = api_html_entity_decode(
stripslashes($lp_name),
ENT_QUOTES,
$charset
);
echo Display::tag('td', stripslashes($lp_name));
}
if (in_array('time', $columnHeadersKeys)) {
$contentToExport[] = api_time_to_hms($total_time);
echo Display::tag('td', api_time_to_hms($total_time));
}
if (is_numeric($progress)) {
$progress = $progress.'%';
} else {
$progress = '-';
}
if (in_array('best_score', $columnHeadersKeys)) {
$contentToExport[] = $bestScore;
echo Display::tag('td', $bestScore);
}
if (in_array('latest_attempt_avg_score', $columnHeadersKeys)) {
$contentToExport[] = $score_latest;
echo Display::tag('td', $score_latest);
}
echo '<tr class="'.$css_class.'">';
$contentToExport = [];
if (in_array('lp', $columnHeadersKeys)) {
$contentToExport[] = api_html_entity_decode(
stripslashes($lp_name),
ENT_QUOTES,
$charset
);
echo Display::tag('td', stripslashes($lp_name));
}
if (in_array('time', $columnHeadersKeys)) {
$contentToExport[] = api_time_to_hms($total_time);
echo Display::tag('td', api_time_to_hms($total_time));
}
if (in_array('progress', $columnHeadersKeys)) {
$contentToExport[] = $progress;
echo Display::tag('td', $progress);
}
if (in_array('best_score', $columnHeadersKeys)) {
$contentToExport[] = $bestScore;
echo Display::tag('td', $bestScore);
}
if (in_array('latest_attempt_avg_score', $columnHeadersKeys)) {
$contentToExport[] = $score_latest;
echo Display::tag('td', $score_latest);
}
if (in_array('last_connection', $columnHeadersKeys)) {
// Do not change with api_convert_and_format_date, because this value came from the lp_item_view table
// which implies several other changes not a priority right now
$contentToExport[] = $start_time;
echo Display::tag('td', $start_time);
}
if (in_array('progress', $columnHeadersKeys)) {
$contentToExport[] = $progress;
echo Display::tag('td', $progress);
}
$csv_content[] = $contentToExport;
if (in_array('last_connection', $columnHeadersKeys)) {
// Do not change with api_convert_and_format_date, because this value came from the lp_item_view table
// which implies several other changes not a priority right now
$contentToExport[] = $start_time;
echo Display::tag('td', $start_time);
if ($any_result === true) {
$from = '';
if ($from_myspace) {
$from = '&from=myspace';
}
$link = Display::url(
Display::return_icon('2rightarrow.png', get_lang('Details')),
'lp_tracking.php?cidReq='.$course_code.'&course='.$course_code.$from.'&origin='.$origin
.'&lp_id='.$lp_id.'&student_id='.$user_info['user_id'].'&id_session='.$sessionId
);
echo Display::tag('td', $link);
}
$csv_content[] = $contentToExport;
if (api_is_allowed_to_edit()) {
echo '<td>';
if ($any_result === true) {
$from = '';
if ($from_myspace) {
$from = '&from=myspace';
}
$link = Display::url(
Display::return_icon('2rightarrow.png', get_lang('Details')),
'lp_tracking.php?cidReq='.$course_code.'&course='.$course_code.$from.'&origin='.$origin
.'&lp_id='.$lp_id.'&student_id='.$user_info['user_id'].'&id_session='.$sessionId
$url = 'myStudents.php?action=reset_lp&sec_token='.$token.'&cidReq='.$course_code.'&course='
.$course_code.'&details='.$details.'&origin='.$origin.'&lp_id='.$lp_id.'&student='
.$user_info['user_id'].'&details=true&id_session='.$sessionId;
echo Display::url(
Display::return_icon('clean.png', get_lang('Clean')),
$url,
[
'onclick' => "javascript:if(!confirm('"
.addslashes(
api_htmlentities(get_lang('AreYouSureToDelete'))
)
."')) return false;",
]
);
echo Display::tag('td', $link);
}
if (api_is_allowed_to_edit()) {
echo '<td>';
if ($any_result === true) {
$url = 'myStudents.php?action=reset_lp&sec_token='.$token.'&cidReq='.$course_code.'&course='
.$course_code.'&details='.$details.'&origin='.$origin.'&lp_id='.$lp_id.'&student='
.$user_info['user_id'].'&details=true&id_session='.$sessionId;
echo Display::url(
Display::return_icon('clean.png', get_lang('Clean')),
$url,
[
'onclick' => "javascript:if(!confirm('"
.addslashes(
api_htmlentities(get_lang('AreYouSureToDelete'))
)
."')) return false;",
]
);
}
echo '</td>';
echo '</tr>';
}
echo '</td>';
echo '</tr>';
}
echo '</tbody></table></div>';
}
echo '</tbody></table></div>';
}
}

@ -17,15 +17,13 @@ $this_section = SECTION_TRACKING;
api_block_anonymous_users();
$export_csv = false;
if (isset($_GET['export']) && $_GET['export'] == 'csv') {
$export_csv = true;
}
$id_coach = api_get_user_id();
if (isset($_GET['id_coach']) && $_GET['id_coach'] != '') {
$id_coach = intval($_GET['id_coach']);
} else {
$id_coach = api_get_user_id();
$id_coach = (int) $_GET['id_coach'];
}
$allowToTrack = api_is_platform_admin(true, true) || api_is_teacher();
@ -35,7 +33,7 @@ if (!$allowToTrack) {
}
$htmlHeadXtra[] = api_get_jqgrid_js();
$interbreadcrumb[] = ["url" => "index.php", "name" => get_lang('MySpace')];
$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('MySpace')];
Display::display_header(get_lang('Sessions'));
if (api_is_platform_admin(true, true)) {
@ -44,11 +42,11 @@ if (api_is_platform_admin(true, true)) {
if (!api_is_session_admin()) {
$menu_items[] = Display::url(
Display::return_icon('statistics.png', get_lang('MyStats'), '', ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH)."auth/my_progress.php"
api_get_path(WEB_CODE_PATH).'auth/my_progress.php'
);
$menu_items[] = Display::url(
Display::return_icon('user.png', get_lang('Students'), [], ICON_SIZE_MEDIUM),
"index.php?view=drh_students&amp;display=yourstudents"
'index.php?view=drh_students&amp;display=yourstudents'
);
$menu_items[] = Display::url(
Display::return_icon('teacher.png', get_lang('Trainers'), [], ICON_SIZE_MEDIUM),
@ -143,7 +141,7 @@ $columns = [
// Column config
$columnModel = [
['name' => 'name', 'index' => 'name', 'width' => '255', 'align' => 'left'],
['name' => 'date', 'index' => 'date', 'width' => '150', 'align' => 'left', 'sortable' => 'false'],
['name' => 'date', 'index' => 'access_start_date', 'width' => '150', 'align' => 'left'],
['name' => 'course_per_session', 'index' => 'course_per_session', 'width' => '150', 'sortable' => 'false'],
['name' => 'student_per_session', 'index' => 'student_per_session', 'width' => '100', 'sortable' => 'false'],
['name' => 'details', 'index' => 'details', 'width' => '100', 'sortable' => 'false'],

@ -228,7 +228,7 @@ if (api_is_drh()) {
$menu_items = [
Display::url(
Display::return_icon('statistics.png', get_lang('MyStats'), '', ICON_SIZE_MEDIUM),
$webCodePath."auth/my_progress.php"
$webCodePath.'auth/my_progress.php'
),
Display::url(
Display::return_icon('user_na.png', get_lang('Students'), [], ICON_SIZE_MEDIUM),
@ -261,7 +261,7 @@ if (api_is_drh()) {
} elseif (api_is_student_boss()) {
$actionsLeft .= Display::url(
Display::return_icon('statistics.png', get_lang('MyStats'), '', ICON_SIZE_MEDIUM),
$webCodePath."auth/my_progress.php"
$webCodePath.'auth/my_progress.php'
);
$actionsLeft .= Display::url(
Display::return_icon('user_na.png', get_lang('Students'), [], ICON_SIZE_MEDIUM),
@ -272,17 +272,17 @@ if (api_is_drh()) {
$webCodePath.'social/my_skills_report.php'
);
$actionsLeft .= Display::url(
Display::return_icon("statistics.png", get_lang('CompanyReport'), [], ICON_SIZE_MEDIUM),
$webCodePath."mySpace/company_reports.php"
Display::return_icon('statistics.png', get_lang('CompanyReport'), [], ICON_SIZE_MEDIUM),
$webCodePath.'mySpace/company_reports.php'
);
$actionsLeft .= Display::url(
Display::return_icon(
"certificate_list.png",
get_lang("GradebookSeeListOfStudentsCertificates"),
'certificate_list.png',
get_lang('GradebookSeeListOfStudentsCertificates'),
[],
ICON_SIZE_MEDIUM
),
$webCodePath."gradebook/certificate_report.php"
$webCodePath.'gradebook/certificate_report.php'
);
}

@ -202,7 +202,7 @@ if (api_is_drh()) {
$menu_items = [
Display::url(
Display::return_icon('statistics.png', get_lang('MyStats'), '', ICON_SIZE_MEDIUM),
$webCodePath."auth/my_progress.php"
$webCodePath.'auth/my_progress.php'
),
Display::url(
Display::return_icon('user_na.png', get_lang('Students'), [], ICON_SIZE_MEDIUM),
@ -235,7 +235,7 @@ if (api_is_drh()) {
} elseif (api_is_student_boss()) {
$actionsLeft .= Display::url(
Display::return_icon('statistics.png', get_lang('MyStats'), '', ICON_SIZE_MEDIUM),
$webCodePath."auth/my_progress.php"
$webCodePath.'auth/my_progress.php'
);
$actionsLeft .= Display::url(
Display::return_icon('user_na.png', get_lang('Students'), [], ICON_SIZE_MEDIUM),
@ -246,17 +246,17 @@ if (api_is_drh()) {
$webCodePath.'social/my_skills_report.php'
);
$actionsLeft .= Display::url(
Display::return_icon("statistics.png", get_lang("CompanyReport"), [], ICON_SIZE_MEDIUM),
$webCodePath."mySpace/company_reports.php"
Display::return_icon('statistics.png', get_lang("CompanyReport"), [], ICON_SIZE_MEDIUM),
$webCodePath.'mySpace/company_reports.php'
);
$actionsLeft .= Display::url(
Display::return_icon(
"certificate_list.png",
get_lang("GradebookSeeListOfStudentsCertificates"),
'certificate_list.png',
get_lang('GradebookSeeListOfStudentsCertificates'),
[],
ICON_SIZE_MEDIUM
),
$webCodePath."gradebook/certificate_report.php"
$webCodePath.'gradebook/certificate_report.php'
);
}

@ -37,6 +37,17 @@ $tool = TOOL_NOTEBOOK;
// Tracking
Event::event_access_tool(TOOL_NOTEBOOK);
$logInfo = [
'tool' => TOOL_NOTEBOOK,
'tool_id' => 0,
'tool_id_detail' => 0,
'action' => $action,
'action_details' => '',
'current_id' => isset($_REQUEST['notebook_id']) ? (int) $_REQUEST['notebook_id'] : 0,
'info' => '',
];
Event::registerLog($logInfo);
$action = isset($_GET['action']) ? $_GET['action'] : '';
// Tool name

@ -111,7 +111,7 @@ if ($invitationcode == 'auto' && isset($_GET['scode'])) {
// Check availability
$row = Database :: fetch_array($result, 'ASSOC');
$tempdata = SurveyManager :: get_survey($row['survey_id']);
check_time_availability($tempdata);
SurveyManager::checkTimeAvailability($tempdata);
// Check for double invitation records (insert should be done once)
$sql = "SELECT user
FROM $table_survey_invitation
@ -157,9 +157,20 @@ if (!isset($_POST['finish_survey']) &&
) ||
($survey_invitation['answered'] == 1 && !isset($_GET['user_id']))
) {
api_not_allowed(true, get_lang('YouAlreadyFilledThisSurvey'));
api_not_allowed(true, Display::return_message(get_lang('YouAlreadyFilledThisSurvey')));
}
$logInfo = [
'tool' => TOOL_SURVEY,
'tool_id' => $survey_invitation['survey_invitation_id'],
'tool_id_detail' => 0,
'action' => 'invitationcode',
'action_details' => $invitationcode,
'current_id' => 0,
'info' => '',
];
Event::registerLog($logInfo);
// Checking if there is another survey with this code.
// If this is the case there will be a language choice
$sql = "SELECT * FROM $table_survey
@ -173,7 +184,6 @@ if (Database::num_rows($result) > 1) {
if ($_POST['language']) {
$survey_invitation['survey_id'] = $_POST['language'];
} else {
// Header
Display :: display_header(get_lang('ToolSurvey'));
$frmLangUrl = api_get_self().'?'.api_get_cidreq().'&'
.http_build_query([
@ -202,6 +212,9 @@ $survey_data = SurveyManager::get_survey($survey_invitation['survey_id']);
if (empty($survey_data)) {
api_not_allowed(true);
}
// Checking time availability
SurveyManager::checkTimeAvailability($survey_data);
$survey_data['survey_id'] = $survey_invitation['survey_id'];
if ($survey_data['survey_type'] == '3') {
@ -522,10 +535,6 @@ if ($survey_data['form_fields'] != '' &&
$form->setDefaults($user_data);
}
// Checking time availability
check_time_availability($survey_data);
// Header
Display::display_header(get_lang('ToolSurvey'));
// Displaying the survey title and subtitle (appears on every page)
@ -646,8 +655,7 @@ if ($survey_data['shuffle'] == 1) {
$shuffle = ' BY RAND() ';
}
if (
(isset($_GET['show']) && $_GET['show'] != '') ||
if ((isset($_GET['show']) && $_GET['show'] != '') ||
isset($_POST['personality'])
) {
// Getting all the questions for this page and add them to a
@ -655,9 +663,10 @@ if (
// As long as there is no pagebreak fount we keep adding questions to the page
$questions_displayed = [];
$counter = 0;
$paged_questions = Session::read('paged_questions');
// If non-conditional survey
if ($survey_data['survey_type'] === '0') {
$paged_questions = [];
// If non-conditional survey
if ($survey_data['survey_type'] == '0') {
if (empty($paged_questions)) {
$sql = "SELECT * FROM $table_survey_question
WHERE
@ -668,16 +677,17 @@ if (
$result = Database::query($sql);
while ($row = Database::fetch_array($result, 'ASSOC')) {
if ($survey_data['one_question_per_page'] == 1) {
$paged_questions[$counter][] = $row['question_id'];
$counter++;
continue;
}
if ($row['type'] == 'pagebreak') {
$counter++;
if ($row['type'] != 'pagebreak') {
$paged_questions[$counter][] = $row['question_id'];
$counter++;
continue;
}
} else {
// ids from question of the current survey
$paged_questions[$counter][] = $row['question_id'];
if ($row['type'] == 'pagebreak') {
$counter++;
} else {
$paged_questions[$counter][] = $row['question_id'];
}
}
}
Session::write('paged_questions', $paged_questions);
@ -692,7 +702,7 @@ if (
if (array_key_exists($_GET['show'], $paged_questions)) {
if (isset($_GET['user_id'])) {
// Get the user into survey answer table (user or anonymus)
$my_user_id = ($survey_data['anonymous'] == 1) ? $surveyUserFromSession : api_get_user_id();
$my_user_id = $survey_data['anonymous'] == 1 ? $surveyUserFromSession : api_get_user_id();
$sql = "SELECT
survey_question.survey_group_sec1,
@ -766,9 +776,6 @@ if (
$questions[$row['sort']]['maximum_score'] = $row['max_value'];
$questions[$row['sort']]['sort'] = $row['sort'];
$questions[$row['sort']]['is_required'] = $allowRequiredSurveyQuestions && $row['is_required'];
} else {
// If the type is a pagebreak we are finished loading the questions for this page
break;
}
$counter++;
}
@ -1169,7 +1176,7 @@ if (
$questions[$row['sort']]['sort'] = $row['sort'];
} else {
// If the type is a page break we are finished loading the questions for this page
break;
//break;
}
$counter++;
}
@ -1180,23 +1187,15 @@ if (
}
}
$numberOfPages = SurveyManager::getCountPages($survey_data);
// Selecting the maximum number of pages
$sql = "SELECT * FROM $table_survey_question
WHERE
c_id = $course_id AND
type = 'pagebreak' AND
survey_id='".intval($survey_invitation['survey_id'])."'";
$result = Database::query($sql);
$numberofpages = Database::num_rows($result) + 1;
// Displaying the form with the questions
$show = 0;
if (isset($_GET['show']) && $_GET['show'] != '') {
$show = (int) $_GET['show'] + 1;
} else {
$show = 0;
}
$displayFinishButton = true;
if (isset($_GET['show']) && $_GET['show'] != '') {
$pagesIndexes = array_keys($paged_questions);
$pagesIndexes[] = count($pagesIndexes);
@ -1207,10 +1206,9 @@ if (isset($_GET['show']) && $_GET['show'] != '') {
}
// Displaying the form with the questions
$personality = 0;
if (isset($_POST['personality'])) {
$personality = (int) $_POST['personality'] + 1;
} else {
$personality = 0;
}
// Displaying the form with the questions
@ -1237,7 +1235,6 @@ $form->addHidden('language', $p_l);
if (isset($questions) && is_array($questions)) {
$originalShow = isset($_GET['show']) ? (int) $_GET['show'] : 0;
$questionCounter = 1;
if (!empty($originalShow)) {
$before = 0;
@ -1251,12 +1248,13 @@ if (isset($questions) && is_array($questions)) {
foreach ($questions as $key => &$question) {
$ch_type = 'ch_'.$question['type'];
//$questionNumber = $question['sort'];
$questionNumber = $questionCounter;
$display = new $ch_type();
// @todo move this in a function.
$form->addHtml('<div class="survey_question '.$ch_type.'">');
$form->addHtml('<h5 class="title">'.$questionNumber.'. '.strip_tags($question['survey_question']).'</h5>');
$form->addHtml('<div style="float:left; font-weight: bold; margin-right: 5px;"> '.$questionNumber.'. </div>');
$form->addHtml('<div>'.Security::remove_XSS($question['survey_question']).'</div> ');
$userAnswerData = SurveyUtil::get_answers_of_question_by_user($question['survey_id'], $question['question_id']);
$finalAnswer = null;
@ -1288,10 +1286,10 @@ if (isset($questions) && is_array($questions)) {
}
$form->addHtml('<div class="start-survey">');
if ($survey_data['survey_type'] === '0') {
if ($survey_data['survey_type'] == '0') {
if ($survey_data['show_form_profile'] == 0) {
// The normal survey as always
if (($show < $numberofpages)) {
if ($show < $numberOfPages) {
if ($show == 0) {
$form->addButton(
'next_survey_page',
@ -1308,7 +1306,7 @@ if ($survey_data['survey_type'] === '0') {
);
}
}
if ($show >= $numberofpages && $displayFinishButton) {
if ($show >= $numberOfPages && $displayFinishButton) {
$form->addButton(
'finish_survey',
get_lang('FinishSurvey'),
@ -1319,8 +1317,8 @@ if ($survey_data['survey_type'] === '0') {
} else {
// The normal survey as always but with the form profile
if (isset($_GET['show'])) {
$numberofpages = count($paged_questions);
if (($show < $numberofpages)) { //$show = $_GET['show'] + 1
$numberOfPages = count($paged_questions);
if ($show < $numberOfPages) {
if ($show == 0) {
$form->addButton(
'next_survey_page',
@ -1338,7 +1336,7 @@ if ($survey_data['survey_type'] === '0') {
}
}
if ($show >= $numberofpages && $displayFinishButton) {
if ($show >= $numberOfPages && $displayFinishButton) {
$form->addButton(
'finish_survey',
get_lang('FinishSurvey'),
@ -1348,13 +1346,13 @@ if ($survey_data['survey_type'] === '0') {
}
}
}
} elseif ($survey_data['survey_type'] === '1') {
} elseif ($survey_data['survey_type'] == '1') {
//conditional/personality-test type survey
if (isset($_GET['show']) || isset($_POST['personality'])) {
$numberofpages = count($paged_questions);
$numberOfPages = count($paged_questions);
if (!empty($paged_questions_sec) && count($paged_questions_sec) > 0) {
// In case we're in the second phase, also sum the second group questions
$numberofpages += count($paged_questions_sec);
$numberOfPages += count($paged_questions_sec);
} else {
// We need this variable only if personality == 1
Session::erase('page_questions_sec');
@ -1362,7 +1360,7 @@ if ($survey_data['survey_type'] === '0') {
}
if ($personality == 0) {
if (($show <= $numberofpages) || !$_GET['show']) {
if (($show <= $numberOfPages) || !$_GET['show']) {
$form->addButton('next_survey_page', get_lang('Next'), 'arrow-right', 'success');
if ($survey_data['one_question_per_page'] == 0) {
if ($personality >= 0) {
@ -1374,17 +1372,17 @@ if ($survey_data['survey_type'] === '0') {
}
}
if ($numberofpages == $show) {
if ($numberOfPages == $show) {
$form->addHidden('personality', $personality);
}
}
}
if ($show > $numberofpages && $_GET['show'] && $personality == 0) {
if ($show > $numberOfPages && $_GET['show'] && $personality == 0) {
$form->addHidden('personality', $personality);
} elseif ($personality > 0) {
if ($survey_data['one_question_per_page'] == 1) {
if ($show >= $numberofpages) {
if ($show >= $numberOfPages) {
$form->addButton('finish_survey', get_lang('FinishSurvey'), 'arrow-right', 'success');
} else {
$form->addHidden('personality', $personality);
@ -1406,41 +1404,3 @@ if ($survey_data['survey_type'] === '0') {
$form->addHtml('</div>');
$form->display();
Display::display_footer();
/**
* Check whether this survey has ended. If so, display message and exit rhis script.
*
* @param array $surveyData Survey data
*/
function check_time_availability($surveyData)
{
$allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
$utcZone = new DateTimeZone('UTC');
$startDate = new DateTime($surveyData['start_date'], $utcZone);
$endDate = new DateTime($surveyData['end_date'], $utcZone);
$currentDate = new DateTime('now', $utcZone);
if (!$allowSurveyAvailabilityDatetime) {
$currentDate->modify('today');
}
if ($currentDate < $startDate) {
api_not_allowed(
true,
Display:: return_message(
get_lang('SurveyNotAvailableYet'),
'warning',
false
)
);
}
if ($currentDate > $endDate) {
api_not_allowed(
true,
Display:: return_message(
get_lang('SurveyNotAvailableAnymore'),
'warning',
false
)
);
}
}

@ -237,7 +237,8 @@ if (api_is_course_admin() ||
/** @var survey_question $display */
$display = new $ch_type();
$form->addHtml('<div class="survey_question '.$ch_type.'">');
$form->addHtml('<h5 class="title">'.$counter.'. '.strip_tags($question['survey_question']).'</h5>');
$form->addHtml('<div style="float:left; font-weight: bold; margin-right: 5px;"> '.$counter.'. </div>');
$form->addHtml('<div>'.Security::remove_XSS($question['survey_question']).'</div> ');
$display->render($form, $question);
$form->addHtml('</div>');
$counter++;
@ -245,7 +246,7 @@ if (api_is_course_admin() ||
}
$form->addHtml('<div class="start-survey">');
if (($show < $numberOfPages)) {
if ($show < $numberOfPages) {
if ($show == 0) {
$form->addButton(
'next_survey_page',

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save