Admin: Add config block_category_questions BT#17789 (WIP)

Requires DB change.
pull/3628/head
Julio Montoya 5 years ago
parent 154dbe881a
commit 9f573d95de
  1. 7
      main/exercise/exercise.class.php
  2. 175
      main/exercise/exercise_question_reminder.php
  3. 1
      main/exercise/exercise_result.php
  4. 186
      main/exercise/exercise_submit.php
  5. 23
      main/install/configuration.dist.php

@ -91,7 +91,6 @@ class Exercise
public $pageResultConfiguration;
public $preventBackwards;
public $currentQuestion;
public $currentBlockedCategories;
public $hideComment;
public $hideNoAnswer;
public $hideExpectedAnswer;
@ -3220,6 +3219,7 @@ class Exercise
* @param array $questions_in_media
* @param string $currentAnswer
* @param array $myRemindList
* @param bool $showPreviousButton
*
* @return string
*/
@ -3228,7 +3228,8 @@ class Exercise
$questionNum,
$questions_in_media = [],
$currentAnswer = '',
$myRemindList = []
$myRemindList = [],
$showPreviousButton = true
) {
global $safe_lp_id, $safe_lp_item_id, $safe_lp_item_view_id;
$nbrQuestions = $this->countQuestionsInExercise();
@ -3332,7 +3333,7 @@ class Exercise
}
}
if ($showPreview && 0 === $this->getPreventBackwards()) {
if ($showPreviousButton && $showPreview && 0 === $this->getPreventBackwards()) {
$buttonList[] = Display::button(
'previous_question_and_save',
get_lang('PreviousQuestion'),

@ -0,0 +1,175 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
require_once __DIR__.'/../inc/global.inc.php';
if (false === api_get_configuration_value('block_category_questions')) {
api_not_allowed(true);
}
$this_section = SECTION_COURSES;
api_protect_course_script(true);
$origin = api_get_origin();
$learnpath_id = isset($_REQUEST['learnpath_id']) ? (int) $_REQUEST['learnpath_id'] : 0;
$learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? (int) $_REQUEST['learnpath_item_id'] : 0;
$learnpath_item_view_id = isset($_REQUEST['learnpath_item_view_id']) ? (int) $_REQUEST['learnpath_item_view_id'] : 0;
$exerciseId = isset($_REQUEST['exerciseId']) ? (int) $_REQUEST['exerciseId'] : 0;
$currentQuestion = isset($_REQUEST['num']) ? (int) $_REQUEST['num'] : 1;
$exeId = isset($_REQUEST['exe_id']) ? (int) $_REQUEST['exe_id'] : 0;
$questionCategoryId = isset($_REQUEST['category_id']) ? (int) $_REQUEST['category_id'] : 0;
$validateCategory = isset($_REQUEST['validate']) && 1 === (int) $_REQUEST['validate'];
/** @var Exercise $objExercise */
$objExercise = null;
$exerciseInSession = Session::read('objExercise');
if (!empty($exerciseInSession)) {
$objExercise = $exerciseInSession;
}
$category = new TestCategory();
$categoryObj = $category->getCategory($questionCategoryId);
if (empty($objExercise) || empty($questionCategoryId) || empty($exeId) || empty($categoryObj)) {
api_not_allowed(true);
}
$categoryId = $categoryObj->id;
$params = "exe_id=$exeId&exerciseId=$exerciseId&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id&".api_get_cidreq();
$url = api_get_path(WEB_CODE_PATH).'exercise/exercise_submit.php?'.$params;
$validateUrl = api_get_self().'?'.$params.'&category_id='.$categoryId.'&validate=1';
$time_control = false;
/*
$clock_expired_time = ExerciseLib::get_session_time_control_key(
$objExercise->id,
$learnpath_id,
$learnpath_item_id
);
if ($objExercise->expired_time != 0 && !empty($clock_expired_time)) {
$time_control = true;
}
if ($time_control) {
// Get time left for expiring time
$time_left = api_strtotime($clock_expired_time, 'UTC') - time();
$htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/stylesheet/jquery.epiclock.css');
$htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/renderers/minute/epiclock.minute.css');
$htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.dateformat.min.js');
$htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.epiclock.min.js');
$htmlHeadXtra[] = api_get_js('epiclock/renderers/minute/epiclock.minute.js');
$htmlHeadXtra[] = $objExercise->showTimeControlJS($time_left);
}
$htmlHeadXtra[] = api_get_css_asset('pretty-checkbox/dist/pretty-checkbox.min.css');*/
$trackInfo = $objExercise->get_stat_track_exercise_info_by_exe_id($exeId);
if (empty($trackInfo)) {
api_not_allowed();
}
$blockedCategories = [];
if (isset($trackInfo['blocked_categories']) && !empty($trackInfo['blocked_categories'])) {
$blockedCategories = explode(',', $trackInfo['blocked_categories']);
}
if ($validateCategory) {
$blockedCategories[] = $categoryId;
$blockedCategories = array_unique($blockedCategories);
$value = implode(',', $blockedCategories);
$value = Database::escape_string($value);
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$sql = "UPDATE $table
SET blocked_categories = '$value'
WHERE exe_id = $exeId";
Database::query($sql);
api_location($url.'&num='.$currentQuestion);
}
$nameTools = get_lang('Exercises');
$interbreadcrumb[] = ['url' => 'exercise.php?'.api_get_cidreq(), 'name' => get_lang('Exercises')];
$hideHeaderAndFooter = in_array($origin, ['learnpath', 'embeddable']);
if (!$hideHeaderAndFooter) {
Display::display_header($nameTools, get_lang('Exercise'));
} else {
Display::display_reduced_header();
}
// I'm in a preview mode as course admin. Display the action menu.
if (api_is_course_admin() && !$hideHeaderAndFooter) {
echo '<div class="actions">';
echo '<a href="admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id.'">'.
Display::return_icon('back.png', get_lang('GoBackToQuestionList'), [], 32).'</a>';
echo '<a href="exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.
Display::return_icon('edit.png', get_lang('ModifyExercise'), [], 32).'</a>';
echo '</div>';
}
echo Display::page_header($categoryObj->name);
echo '<p>'.Security::remove_XSS($categoryObj->description).'</p>';
echo '<p>'.get_lang('BlockCategoryExplanation').'</p>';
if ($time_control) {
echo $objExercise->returnTimeLeftDiv();
}
echo Display::div('', ['id' => 'message']);
$previousQuestion = $currentQuestion - 1;
echo '<script>
var lp_data = $.param({
"learnpath_id": '.$learnpath_id.',
"learnpath_item_id" : '.$learnpath_item_id.',
"learnpath_item_view_id": '.$learnpath_item_view_id.'
});
function goBack() {
window.location = "'.$url.'&num='.$previousQuestion.'&" + lp_data;
}
function continueExercise() {
window.location = "'.$validateUrl.'&num='.$currentQuestion.'&" + lp_data;
}
function final_submit() {
window.location = "'.api_get_path(WEB_CODE_PATH).'exercise/exercise_result.php?'.api_get_cidreq().'&exe_id='.$exeId.'&" + lp_data;
}
</script>';
$exercise_result = $objExercise->getUserAnswersSavedInExercise($exeId);
echo '<div class="clear"></div><br />';
$table = '';
$counter = 0;
echo Display::div($table, ['class' => 'question-check-test']);
$exerciseActions = '';
if (!in_array($categoryId, $blockedCategories)) {
$exerciseActions = '&nbsp;'.Display::url(
get_lang('GoBack'),
'javascript://',
['onclick' => 'goBack();', 'class' => 'btn btn-default']
);
}
$exerciseActions .= '&nbsp;'.Display::url(
get_lang('ContinueTest'),
'javascript://',
['onclick' => 'continueExercise();', 'class' => 'btn btn-primary']
);
/*
$exerciseActions .= '&nbsp;'.Display::url(
get_lang('EndTest'),
'javascript://',
['onclick' => 'final_submit();', 'class' => 'btn btn-warning']
);*/
echo Display::div('', ['class' => 'clear']);
echo Display::div($exerciseActions, ['class' => 'form-actions']);
if (!$hideHeaderAndFooter) {
// We are not in learnpath tool or embeddable quiz
Display::display_footer();
} else {
Display::display_reduced_footer();
}

@ -31,7 +31,6 @@ if (empty($objExercise)) {
}
$exeId = isset($_REQUEST['exe_id']) ? (int) $_REQUEST['exe_id'] : 0;
if (empty($objExercise)) {
// Redirect to the exercise overview
// Check if the exe_id exists

@ -40,13 +40,16 @@ $is_allowedToEdit = api_is_allowed_to_edit(null, true);
$courseId = api_get_course_int_id();
$sessionId = api_get_session_id();
$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
$showPreviousButton = true;
$showGlossary = in_array($glossaryExtraTools, ['true', 'exercise', 'exercise_and_lp']);
if ('learnpath' == $origin) {
if ('learnpath' === $origin) {
$showGlossary = in_array($glossaryExtraTools, ['true', 'lp', 'exercise_and_lp']);
}
if ($showGlossary) {
$htmlHeadXtra[] = '<script type="text/javascript" src="'.api_get_path(WEB_CODE_PATH).'glossary/glossary.js.php?add_ready=1&'.api_get_cidreq().'"></script>';
$htmlHeadXtra[] = '<script
type="text/javascript"
src="'.api_get_path(WEB_CODE_PATH).'glossary/glossary.js.php?add_ready=1&'.api_get_cidreq().'"></script>';
$htmlHeadXtra[] = api_get_js('jquery.highlight.js');
}
@ -116,7 +119,6 @@ $template = new Template();
$learnpath_id = isset($_REQUEST['learnpath_id']) ? (int) $_REQUEST['learnpath_id'] : 0;
$learnpath_item_id = isset($_REQUEST['learnpath_item_id']) ? (int) $_REQUEST['learnpath_item_id'] : 0;
$learnpath_item_view_id = isset($_REQUEST['learnpath_item_view_id']) ? (int) $_REQUEST['learnpath_item_view_id'] : 0;
$reminder = isset($_REQUEST['reminder']) ? (int) $_REQUEST['reminder'] : 0;
$remind_question_id = isset($_REQUEST['remind_question_id']) ? (int) $_REQUEST['remind_question_id'] : 0;
$exerciseId = isset($_REQUEST['exerciseId']) ? (int) $_REQUEST['exerciseId'] : 0;
@ -125,10 +127,10 @@ $exerciseResult = isset($_REQUEST['exerciseResult']) ? $_REQUEST['exerciseResult
$exerciseResultCoordinates = isset($_REQUEST['exerciseResultCoordinates']) ? $_REQUEST['exerciseResultCoordinates'] : null;
$choice = isset($_REQUEST['choice']) ? $_REQUEST['choice'] : null;
$choice = empty($choice) ? isset($_REQUEST['choice2']) ? $_REQUEST['choice2'] : null : null;
// From submit modal
$questionCategoryId = isset($_REQUEST['category_id']) ? (int) $_REQUEST['category_id'] : 0;
$current_question = isset($_REQUEST['num']) ? (int) $_REQUEST['num'] : null;
$currentAnswer = isset($_REQUEST['num_answer']) ? (int) $_REQUEST['num_answer'] : null;
$logInfo = [
'tool' => TOOL_QUIZ,
'tool_id' => $exerciseId,
@ -152,7 +154,7 @@ if (api_is_allowed_to_edit(null, true) &&
// 1. Loading the $objExercise variable
/** @var \Exercise $exerciseInSession */
$exerciseInSession = Session::read('objExercise');
if (empty($exerciseInSession) || (!empty($exerciseInSession) && ($exerciseInSession->id != $_GET['exerciseId']))) {
if (empty($exerciseInSession) || (!empty($exerciseInSession) && $exerciseInSession->id != $_GET['exerciseId'])) {
// Construction of Exercise
$objExercise = new Exercise($courseId);
Session::write('firstTime', true);
@ -165,9 +167,6 @@ if (empty($exerciseInSession) || (!empty($exerciseInSession) && ($exerciseInSess
if (!$objExercise->read($exerciseId) ||
(!$objExercise->selectStatus() && !$is_allowedToEdit && !in_array($origin, ['learnpath', 'embeddable']))
) {
if ($debug) {
error_log('1.1. Error while reading the exercise');
}
unset($objExercise);
$error = get_lang('ExerciseNotFound');
} else {
@ -193,9 +192,6 @@ $exerciseInSession = Session::read('objExercise');
//3. $objExercise is not set, then return to the exercise list
if (!is_object($objExercise)) {
if ($debug) {
error_log('3. $objExercise was not set, kill the script');
}
header('Location: exercise.php');
exit;
}
@ -219,7 +215,6 @@ $htmlHeadXtra[] = $template->fetch($templateName);
$current_timestamp = time();
$myRemindList = [];
$time_control = false;
if (0 != $objExercise->expired_time) {
$time_control = true;
@ -287,7 +282,6 @@ if ($objExercise->selectAttempts() > 0) {
if ($isQuestionsLimitReached) {
$maxQuestionsAnswered = (int) api_get_course_setting('quiz_question_limit_per_day');
Display::addFlash(
Display::return_message(
sprintf(get_lang('QuizQuestionsLimitPerDayXReached'), $maxQuestionsAnswered),
@ -303,7 +297,6 @@ if ($objExercise->selectAttempts() > 0) {
Display::display_header(get_lang('Exercises'));
Display::display_footer();
}
exit;
}
@ -321,7 +314,6 @@ if ($objExercise->selectAttempts() > 0) {
foreach ($questions as $question_data) {
$question_id = $question_data['question_id'];
$marks = $question_data['marks'];
$question_info = Question::read($question_id);
$attempt_html .= Display::div(
$question_info->question,
@ -359,7 +351,6 @@ if ($objExercise->selectAttempts() > 0) {
}
echo $attempt_html;
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_footer();
}
@ -367,8 +358,7 @@ if ($objExercise->selectAttempts() > 0) {
}
}
/* 5. Getting user exercise info (if the user took the exam before)
generating exe_id */
/* 5. Getting user exercise info (if the user took the exam before) generating exe_id */
$exercise_stat_info = $objExercise->get_stat_track_exercise_info(
$learnpath_id,
$learnpath_item_id,
@ -384,23 +374,17 @@ if (empty($exercise_stat_info)) {
if ($disable) {
api_not_allowed(true);
}
if ($debug) {
error_log('5 $exercise_stat_info is empty ');
}
$total_weight = 0;
$questionList = $objExercise->get_validated_question_list();
foreach ($questionListUncompressed as $question_id) {
$objQuestionTmp = Question::read($question_id);
$total_weight += floatval($objQuestionTmp->weighting);
$total_weight += (float) $objQuestionTmp->weighting;
}
if ($time_control) {
$expected_time = $current_timestamp + $total_seconds;
if ($debug) {
error_log('5.1. $current_timestamp '.$current_timestamp);
}
if ($debug) {
error_log('5.2. $expected_time '.$expected_time);
}
@ -443,14 +427,10 @@ if (empty($exercise_stat_info)) {
$exe_id
);
}
if ($debug) {
error_log("5.5 exercise_stat_info[] exists getting exe_id $exe_id");
}
} else {
$exe_id = $exercise_stat_info['exe_id'];
// Remember last question id position.
$isFirstTime = Session::read('firstTime');
if ($isFirstTime && ONE_PER_PAGE == $objExercise->type) {
$resolvedQuestions = Event::getAllExerciseEventByExeId($exe_id);
if (!empty($resolvedQuestions) &&
@ -468,14 +448,11 @@ if (empty($exercise_stat_info)) {
$current_question = $count;
}
}
if ($debug) {
error_log("5 exercise_stat_info[] exists getting exe_id $exe_id ");
}
}
$saveDurationUrl = api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?a=update_duration&exe_id='.$exe_id.'&'.api_get_cidreq();
$questionListInSession = Session::read('questionList');
$selectionType = $objExercise->getQuestionSelectionType();
if (!isset($questionListInSession)) {
// Selects the list of question ID
@ -483,18 +460,25 @@ if (!isset($questionListInSession)) {
// Media questions.
$media_is_activated = $objExercise->mediaIsActivated();
// Getting order from random
if ($media_is_activated == false &&
(
$objExercise->isRandom() ||
!empty($objExercise->getRandomByCategory()) ||
$objExercise->getQuestionSelectionType() > 2
$selectionType > EX_Q_SELECTION_RANDOM
) &&
isset($exercise_stat_info) &&
!empty($exercise_stat_info['data_tracking'])
) {
$questionList = explode(',', $exercise_stat_info['data_tracking']);
$categoryList = [];
if (api_get_configuration_value('block_category_questions')) {
foreach ($questionList as $question) {
$categoryId = TestCategory::getCategoryForQuestion($question);
$categoryList[$categoryId][] = $question;
}
Session::write('categoryList', $categoryList);
}
}
Session::write('questionList', $questionList);
} else {
@ -505,15 +489,6 @@ if (!isset($questionListInSession)) {
// Array to check in order to block the chat
ExerciseLib::create_chat_exercise_session($exe_id);
if ($debug) {
error_log(
'6. $objExercise->get_stat_track_exercise_info function called:: '.print_r(
$exercise_stat_info,
1
)
);
}
if (!empty($exercise_stat_info['questions_to_check'])) {
$myRemindList = $exercise_stat_info['questions_to_check'];
$myRemindList = explode(',', $myRemindList);
@ -527,7 +502,7 @@ if ($debug) {
if (2 == $reminder && empty($myRemindList)) {
if ($debug) {
error_log('6.2 calling the exercise_reminder.php ');
error_log('6.2 calling the exercise_reminder.php');
}
header('Location: exercise_reminder.php?'.$params);
exit;
@ -615,7 +590,7 @@ if ($time_control) { //Sends the exercise form when the expired time is finished
$htmlHeadXtra[] = $objExercise->showTimeControlJS($time_left);
}
//in LP's is enabled the "remember question" feature?
// in LP's is enabled the "remember question" feature?
if (!isset($_SESSION['questionList'])) {
// selects the list of question ID
$questionList = $objExercise->get_validated_question_list();
@ -629,6 +604,91 @@ if (!isset($_SESSION['questionList'])) {
}
}
$isLastQuestionInCategory = 0;
if (
api_get_configuration_value('block_category_questions') &&
ONE_PER_PAGE == $objExercise->type &&
EX_Q_SELECTION_CATEGORIES_ORDERED_QUESTIONS_RANDOM == $selectionType
) {
// Check current attempt.
$currentAttempt = Event::get_exercise_results_by_attempt($exe_id, 'incomplete');
$answeredQuestions = [];
if (!empty($currentAttempt) && isset($currentAttempt[$exe_id]) &&
isset($currentAttempt[$exe_id]['question_list'])
) {
$answeredQuestions = array_keys($currentAttempt[$exe_id]['question_list']);
}
//var_dump($exe_id, $answeredQuestions);
$categoryAllResolved = [];
$categoryList = Session::read('categoryList');
foreach ($categoryList as $categoryId => $categoryQuestionList) {
$categoryAllResolved[$categoryId] = false;
$answered = 1;
foreach ($categoryQuestionList as $questionInCategoryId) {
if (in_array($questionInCategoryId, $answeredQuestions)) {
$answered++;
break;
}
}
if ($answered === count($categoryList[$categoryId])) {
$categoryAllResolved[$categoryId] = true;
}
}
$blockedCategories = [];
if (isset($exercise_stat_info['blocked_categories']) && !empty($exercise_stat_info['blocked_categories'])) {
$blockedCategories = explode(',', $exercise_stat_info['blocked_categories']);
}
$count = 0;
$questionCheck = null;
foreach ($questionList as $questionId) {
// if it is not the right question, goes to the next loop iteration
if ((int) $current_question === $count) {
$questionCheck = Question::read($questionId);
break;
}
$count++;
}
$categoryId = 0;
if (null !== $questionCheck) {
$categoryId = $questionCheck->category;
}
if (!empty($categoryId)) {
$categoryInfo = $categoryList[$categoryId];
$count = 1;
$total = count($categoryList[$categoryId]);
//var_dump($categoryList[$categoryId]);
foreach ($categoryList[$categoryId] as $checkQuestionId) {
if ((int) $checkQuestionId === $questionCheck->iid) {
break;
}
$count++;
}
if ($count === $total) {
$isLastQuestionInCategory = $categoryId;
}
//var_dump($isLastQuestionInCategory, $blockedCategories);
if (0 === $isLastQuestionInCategory) {
$showPreviousButton = false;
}
}
//var_dump($categoryInfo, $count, $total);
// Blocked if category was already answered
if ($categoryId && in_array($categoryId, $blockedCategories)) {
// Redirect to category intro
$url = api_get_path(WEB_CODE_PATH).'exercise/exercise_question_reminder.php?'.
$params.'&num='.$current_question.'&category_id='.$isLastQuestionInCategory;
api_location($url);
}
}
if ($debug) {
error_log('8. Question list loaded '.print_r($questionList, 1));
}
@ -695,9 +755,6 @@ if ($formSent && isset($_POST)) {
$choice = $exerciseResult[$questionId];
if (isset($exe_id)) {
// Manage the question and answer attempts
if ($debug) {
error_log('8.3. manage_answer exe_id: '.$exe_id.' - $questionId: '.$questionId.' Choice'.print_r($choice, 1));
}
$objExercise->manage_answer(
$exe_id,
$questionId,
@ -881,14 +938,13 @@ $interbreadcrumb[] = ['url' => '#', 'name' => $objExercise->selectTitle(true)];
if (!in_array($origin, ['learnpath', 'embeddable', 'mobileapp'])) { //so we are not in learnpath tool
SessionManager::addFlashSessionReadOnly();
Display::display_header(null, 'Exercises');
} else {
Display::display_reduced_header();
echo '<div style="height:10px">&nbsp;</div>';
}
if ($origin == 'mobileapp') {
if ($origin === 'mobileapp') {
echo '<div class="actions">';
echo '<a href="javascript:window.history.go(-1);">'.
Display::return_icon('back.png', get_lang('GoBackToQuestionList'), [], 32).'</a>';
@ -932,17 +988,15 @@ if (!api_is_allowed_to_session_edit()) {
}
$exercise_timeover = false;
$limit_time_exists = (!empty($objExercise->start_time) || !empty($objExercise->end_time)) ? true : false;
$limit_time_exists = !empty($objExercise->start_time) || !empty($objExercise->end_time) ? true : false;
if ($limit_time_exists) {
$exercise_start_time = api_strtotime($objExercise->start_time, 'UTC');
$exercise_end_time = api_strtotime($objExercise->end_time, 'UTC');
$time_now = time();
$permission_to_start = true;
if (!empty($objExercise->start_time)) {
$permission_to_start = (($time_now - $exercise_start_time) > 0) ? true : false;
} else {
$permission_to_start = true;
}
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
if (!empty($objExercise->end_time)) {
@ -1000,7 +1054,6 @@ if (isset($_custom['exercises_hidden_when_no_start_date']) &&
}
}
// Timer control
if ($time_control) {
echo $objExercise->returnTimeLeftDiv();
echo '<div style="display:none" class="warning-message" id="expired-message-id">'.
@ -1012,13 +1065,9 @@ if (!in_array($origin, ['learnpath', 'embeddable'])) {
}
if ($reminder == 2) {
if ($debug) {
error_log(' $reminder == 2');
}
$data_tracking = $exercise_stat_info['data_tracking'];
$data_tracking = explode(',', $data_tracking);
$current_question = 1; //set by default the 1st question
if (!empty($myRemindList)) {
// Checking which questions we are going to call from the remind list
for ($i = 0; $i < count($data_tracking); $i++) {
@ -1234,12 +1283,12 @@ if (!empty($error)) {
});
function previous_question(question_num) {
url = "exercise_submit.php?'.$params.'&num="+question_num;
var url = "exercise_submit.php?'.$params.'&num="+question_num;
window.location = url;
}
function previous_question_and_save(previous_question_id, question_id_to_save) {
url = "exercise_submit.php?'.$params.'&num="+previous_question_id;
var url = "exercise_submit.php?'.$params.'&num="+previous_question_id;
//Save the current question
save_now(question_id_to_save, url);
}
@ -1326,13 +1375,18 @@ if (!empty($error)) {
'&remind_question_id='.$remind_question_id.'";
}
// If last question in category send to exercise_question_reminder.php
if ('.$isLastQuestionInCategory.' > 0 ) {
url = "exercise_question_reminder.php?'.$params.'&num='.$current_question.
'&category_id='.$isLastQuestionInCategory.'";
}
if (url_extra) {
url = url_extra;
}
$("#save_for_now_"+question_id).html(\''.
Display::return_icon('save.png', get_lang('Saved'), [], ICON_SIZE_SMALL).'\');
// window.quizTimeEnding will be reset in exercise.class.php
if (window.quizTimeEnding) {
redirectExerciseToResult();
@ -1528,7 +1582,6 @@ if (!empty($error)) {
}
echo '<div id="question_div_'.$questionId.'" class="main-question '.$remind_highlight.'" >';
$showQuestion = true;
$exerciseResultFromSession = Session::read('exerciseResult');
if ($objExercise->getFeedbackType() === EXERCISE_FEEDBACK_TYPE_POPUP &&
@ -1565,7 +1618,8 @@ if (!empty($error)) {
$current_question,
[],
[],
$myRemindList
$myRemindList,
$showPreviousButton
);
break;
case ALL_ON_ONE_PAGE:

@ -1111,18 +1111,17 @@ $_configuration['profile_fields_visibility'] = [
// Improve speed when rendering gradebook student reports using Doctrine APCU cache
// $_configuration['gradebook_use_apcu_cache'] = true;
// Add a minimum time limit to be in the learning path
// in order to get the last item completed
// Requires a DB change:
/*
ALTER TABLE c_lp ADD accumulate_work_time INT NOT NULL;
CREATE TABLE track_e_access_complete (id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, date_reg datetime NOT NULL, tool varchar(255) NOT NULL, tool_id int(11) NOT NULL, tool_id_detail int(11) NOT NULL, action varchar(255) NOT NULL, action_details varchar(255) NOT NULL, current_id int(11) NOT NULL, ip_user varchar(255) NOT NULL, user_agent varchar(255) NOT NULL, session_id int(11) NOT NULL, c_id int(11) NOT NULL, ch_sid varchar(255) NOT NULL, login_as int(11) NOT NULL, info longtext NOT NULL, url text NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=13989 DEFAULT CHARSET=utf8;
CREATE INDEX user_course_session ON track_e_access_complete (user_id, c_id, session_id);
Add a minimum time limit to be in the learning path
in order to get the last item completed
Requires a DB change:
ALTER TABLE c_lp ADD accumulate_work_time INT NOT NULL;
CREATE TABLE track_e_access_complete (id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, date_reg datetime NOT NULL, tool varchar(255) NOT NULL, tool_id int(11) NOT NULL, tool_id_detail int(11) NOT NULL, action varchar(255) NOT NULL, action_details varchar(255) NOT NULL, current_id int(11) NOT NULL, ip_user varchar(255) NOT NULL, user_agent varchar(255) NOT NULL, session_id int(11) NOT NULL, c_id int(11) NOT NULL, ch_sid varchar(255) NOT NULL, login_as int(11) NOT NULL, info longtext NOT NULL, url text NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=13989 DEFAULT CHARSET=utf8;
CREATE INDEX user_course_session ON track_e_access_complete (user_id, c_id, session_id);
Add course checkbox extra field "new_tracking_system"
Add session checkbox extra field "new_tracking_system"
Only applied for courses/sessions with extra field "new_tracking_system" to "1"
*/
// Add course checkbox extra field "new_tracking_system"
// Add session checkbox extra field "new_tracking_system"
// Only applied for courses/sessions with extra field "new_tracking_system" to "1"
//$_configuration['lp_minimum_time'] = false;
// Track LP attempts using the new tracking system.
@ -1705,6 +1704,10 @@ $_configuration['auth_password_links'] = [
// Show a link on the results page to download an answers report
// $_configuration['quiz_results_answers_report'] = false;
// Block question categories BT#17789
//ALTER TABLE track_e_exercises ADD COLUMN blocked_categories TEXT;
//$_configuration['block_category_questions'] = false;
// KEEP THIS AT THE END
// -------- Custom DB changes
// Add user activation by confirmation email

Loading…
Cancel
Save