Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions public/main/exercise/exercise.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -10133,15 +10133,18 @@ public static function saveExerciseInLp($safe_item_id, $safe_exe_id, $course_id
$exercise->read($row_dates['exe_exo_id']);
$status = 'completed';

if (!empty($exercise->pass_percentage)) {
$status = 'failed';
$success = ExerciseLib::isSuccessExerciseResult(
$score,
$max_score,
$exercise->pass_percentage
);
if ($success) {
$status = 'passed';
// Adaptive / self-evaluation quizzes must always complete the LP item
if ($exercise->getFeedbackType() !== EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (!empty($exercise->pass_percentage)) {
$status = 'failed';
$success = ExerciseLib::isSuccessExerciseResult(
$score,
$max_score,
$exercise->pass_percentage
);
if ($success) {
$status = 'passed';
}
}
}

Expand Down
85 changes: 75 additions & 10 deletions public/main/exercise/exercise_submit.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,60 @@
$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;

// If we are not explicitly in LP context, ignore any leaked LP params and clear persisted context.
// This avoids attaching standalone exercises to the last learning path attempt.
if ('learnpath' !== $origin) {
Session::erase('learnpath_id');
Session::erase('lp_id');
Session::erase('learnpath_item_id');
Session::erase('lp_item_id');
Session::erase('learnpath_item_view_id');
Session::erase('lp_item_view_id');

$learnpath_id = 0;
$learnpath_item_id = 0;
$learnpath_item_view_id = 0;
}

if ('learnpath' === $origin) {
// Normalize common aliases used by LP tool
$learnpath_id = $learnpath_id > 0 ? $learnpath_id : (int) ($_REQUEST['lp_id'] ?? 0);

// Some links use item_id instead of learnpath_item_id
$learnpath_item_id = $learnpath_item_id > 0
? $learnpath_item_id
: (int) ($_REQUEST['item_id'] ?? ($_REQUEST['lp_item_id'] ?? 0));

$learnpath_item_view_id = $learnpath_item_view_id > 0
? $learnpath_item_view_id
: (int) ($_REQUEST['lp_item_view_id'] ?? 0);

// Restore from session when modal/navigation loses query params
if ($learnpath_id <= 0) {
$learnpath_id = (int) (Session::read('learnpath_id') ?? Session::read('lp_id') ?? 0);
}
if ($learnpath_item_id <= 0) {
$learnpath_item_id = (int) (Session::read('learnpath_item_id') ?? Session::read('lp_item_id') ?? 0);
}
if ($learnpath_item_view_id <= 0) {
$learnpath_item_view_id = (int) (Session::read('learnpath_item_view_id') ?? Session::read('lp_item_view_id') ?? 0);
}

// Persist context for future requests (modal, JS navigation, session resume)
if ($learnpath_id > 0) {
Session::write('learnpath_id', $learnpath_id);
Session::write('lp_id', $learnpath_id);
}
if ($learnpath_item_id > 0) {
Session::write('learnpath_item_id', $learnpath_item_id);
Session::write('lp_item_id', $learnpath_item_id);
}
if ($learnpath_item_view_id > 0) {
Session::write('learnpath_item_view_id', $learnpath_item_view_id);
Session::write('lp_item_view_id', $learnpath_item_view_id);
}
}

$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;
Expand Down Expand Up @@ -572,6 +626,20 @@
. "&page=" . ($page ?? 1)
. "&" . api_get_cidreq();

// Base query strings used by JS navigation (keep LP context on every click).
$submitBaseQuery = "exe_id=$exe_id&exerciseId=$exerciseId"
. "&learnpath_id=$learnpath_id"
. "&learnpath_item_id=$learnpath_item_id"
. "&learnpath_item_view_id=$learnpath_item_view_id"
. "&reminder=$reminder"
. "&" . api_get_cidreq();

$resultBaseQuery = "exe_id=$exe_id"
. "&learnpath_id=$learnpath_id"
. "&learnpath_item_id=$learnpath_item_id"
. "&learnpath_item_view_id=$learnpath_item_view_id"
. "&" . api_get_cidreq();


if (2 === $reminder && empty($myRemindList)) {
if ($debug) {
Expand Down Expand Up @@ -1533,12 +1601,14 @@ function updateDuration() {

var page = '.(int) $page.';
var totalPages = '.(int) ($totalPages ?? 1).';
var chSubmitBaseUrl = "'.api_get_self().'?'.$submitBaseQuery.'";
var chResultUrl = "exercise_result.php?'.$resultBaseQuery.'";
function navigateNext() {
var url;
if (page === totalPages) {
url = "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.'";
url = chResultUrl;
} else {
url = "'.api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exerciseId.'&page=" + (page + 1) + "&reminder='.$reminder.'";
url = chSubmitBaseUrl + "&page=" + (page + 1);
}
window.location = url;
}
Expand Down Expand Up @@ -1682,11 +1752,8 @@ function previous_question(question_num) {
}

function previous_question_and_save(previous_question_id, question_id_to_save) {
var url = \'exercise_submit.php?'.api_get_cidreq().'\'
+ \'&exerciseId='.$exerciseId.'\'
+ \'&num=\' + previous_question_id
+ \'&reminder='.$reminder.'\';
save_now(question_id_to_save, url);
var url = chSubmitBaseUrl + "&num=" + previous_question_id;
save_now(question_id_to_save, url);
}

function redirectExerciseToResult()
Expand Down Expand Up @@ -2150,9 +2217,7 @@ function validate_all() {
$currentPageIds = implode(',', $questionList);
echo '<div class="exercise_actions exercise-pagination mb-4">';
if ($page > 1) {
$prevUrl = api_get_self() . '?' . api_get_cidreq()
. "&exerciseId=$exerciseId&page=" . ($page - 1)
. "&reminder=$reminder";
$prevUrl = api_get_self() . '?' . $submitBaseQuery . "&page=" . ($page - 1);
echo '<button type="button" class="btn btn--secondary" '
. "onclick=\"window.location='$prevUrl'\">"
. '‹ ' . get_lang('Previous')
Expand Down
34 changes: 31 additions & 3 deletions public/main/exercise/exercise_submit_modal.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,37 @@
api_not_allowed();
}

$learnpath_id = (int) ($_REQUEST['learnpath_id'] ?? 0);
$learnpath_item_id = (int) ($_REQUEST['learnpath_item_id'] ?? 0);
$learnpath_item_view_id = (int) ($_REQUEST['learnpath_item_view_id'] ?? 0);
$learnpath_id = (int) ($_REQUEST['learnpath_id'] ?? ($_REQUEST['lp_id'] ?? 0));
$learnpath_item_id = (int) ($_REQUEST['learnpath_item_id'] ?? ($_REQUEST['item_id'] ?? ($_REQUEST['lp_item_id'] ?? 0)));
$learnpath_item_view_id = (int) ($_REQUEST['learnpath_item_view_id'] ?? ($_REQUEST['lp_item_view_id'] ?? 0));

$origin = api_get_origin();

// Only restore LP context from session when we are really in learnpath origin.
// Otherwise, stale LP session values can leak into standalone exercises.
if ('learnpath' === $origin) {
if ($learnpath_id <= 0) {
$learnpath_id = (int) (Session::read('learnpath_id') ?? Session::read('lp_id') ?? 0);
}
if ($learnpath_item_id <= 0) {
$learnpath_item_id = (int) (Session::read('learnpath_item_id') ?? Session::read('lp_item_id') ?? 0);
}
if ($learnpath_item_view_id <= 0) {
$learnpath_item_view_id = (int) (Session::read('learnpath_item_view_id') ?? Session::read('lp_item_view_id') ?? 0);
}
} else {
Session::erase('learnpath_id');
Session::erase('lp_id');
Session::erase('learnpath_item_id');
Session::erase('lp_item_id');
Session::erase('learnpath_item_view_id');
Session::erase('lp_item_view_id');

$learnpath_id = 0;
$learnpath_item_id = 0;
$learnpath_item_view_id = 0;
}

$exerciseId = (int) ($_GET['exerciseId'] ?? 0);
$exeId = (int) (Session::read('exe_id') ?? 0);
$preview = (int) ($_GET['preview'] ?? 0);
Expand Down
Loading