Exercise: fix code from 1.11.x

pull/3706/head
Julio Montoya 4 years ago
parent 45c9ff3977
commit 11526bb679
  1. 8
      public/main/exercise/TestCategory.php
  2. 6
      public/main/exercise/admin.php
  3. 12
      public/main/exercise/exercise.class.php
  4. 6
      public/main/exercise/exercise_admin.php
  5. 1
      public/main/exercise/exercise_report.php
  6. 4
      public/main/exercise/exercise_result.php
  7. 2
      public/main/exercise/exercise_show.php
  8. 51
      public/main/exercise/exercise_submit_modal.php
  9. 4
      public/main/exercise/export/aiken/aiken_import.inc.php
  10. 10
      public/main/exercise/export/exercise_import.inc.php
  11. 8
      public/main/exercise/export/qti2/qti2_export.php
  12. 25
      public/main/exercise/fill_blanks.class.php
  13. 52
      public/main/exercise/hotspot_answers.as.php
  14. 2
      public/main/exercise/hotspot_savescore.inc.php
  15. 6
      public/main/exercise/hotspot_updatescore.inc.php
  16. 4
      public/main/exercise/live_stats.php
  17. 4
      public/main/exercise/multiple_answer.class.php
  18. 4
      public/main/exercise/multiple_answer_combination.class.php
  19. 26
      public/main/exercise/multiple_answer_true_false.class.php
  20. 26
      public/main/exercise/overview.php
  21. 33
      public/main/exercise/question.class.php
  22. 8
      public/main/exercise/question_admin.inc.php
  23. 2
      public/main/exercise/question_create.php
  24. 10
      public/main/exercise/question_list_admin.inc.php
  25. 6
      public/main/exercise/question_pool.php
  26. 71
      public/main/exercise/result.php
  27. 30
      public/main/exercise/stats.php
  28. 1
      public/main/exercise/tests_category.php
  29. 4
      public/main/exercise/unique_answer.class.php
  30. 4
      public/main/exercise/unique_answer_no_option.class.php
  31. 14
      public/main/exercise/upload_exercise.php
  32. 6
      public/main/inc/ajax/exercise.ajax.php
  33. 1
      public/main/inc/lib/api.lib.php
  34. 865
      public/main/inc/lib/events.lib.php
  35. 789
      public/main/inc/lib/exercise.lib.php
  36. 79
      public/main/inc/lib/exercise_show_functions.lib.php
  37. 19
      src/CoreBundle/Entity/TrackEAttempt.php
  38. 19
      src/CoreBundle/Entity/TrackEAttemptRecording.php
  39. 4
      src/CoreBundle/Migrations/Schema/V200/Version20180904175500.php

@ -205,13 +205,13 @@ class TestCategory
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$categories = [];
if (empty($field)) {
$sql = "SELECT id FROM $table
$sql = "SELECT iid FROM $table
WHERE c_id = $courseId
ORDER BY title ASC";
$res = Database::query($sql);
while ($row = Database::fetch_array($res)) {
$category = new TestCategory();
$categories[] = $category->getCategory($row['id'], $courseId);
$categories[] = $category->getCategory($row['iid'], $courseId);
}
} else {
$field = Database::escape_string($field);
@ -265,7 +265,7 @@ class TestCategory
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$sql = "SELECT *
FROM $table
WHERE question_id = $questionId AND c_id = $courseId";
WHERE question_id = $questionId";
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
return Database::fetch_array($res, 'ASSOC');
@ -294,7 +294,7 @@ class TestCategory
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$sql = "SELECT title
FROM $table
WHERE id = $categoryId AND c_id = $courseId";
WHERE iid = $categoryId AND c_id = $courseId";
$res = Database::query($sql);
$data = Database::fetch_array($res);
$result = '';

@ -147,7 +147,7 @@ if ($objExercise->sessionId != $sessionId) {
// doesn't select the exercise ID if we come from the question pool
if (!$fromExercise) {
// gets the right exercise ID, and if 0 creates a new exercise
if (!$exerciseId = $objExercise->selectId()) {
if (!$exerciseId = $objExercise->getId()) {
$modifyExercise = 'yes';
}
}
@ -171,7 +171,7 @@ if ($editQuestion || $newQuestion || $modifyQuestion || $modifyAnswers) {
// checks if the object exists
if (is_object($objQuestion)) {
// gets the question ID
$questionId = $objQuestion->selectId();
$questionId = $objQuestion->getId();
}
}
@ -436,7 +436,7 @@ if ($newQuestion || $editQuestion) {
echo '</div>';
} else {
require 'question_admin.inc.php';
ExerciseLib::showTestsWhereQuestionIsUsed($objQuestion->iid, $objExercise->selectId());
ExerciseLib::showTestsWhereQuestionIsUsed($objQuestion->iid, $objExercise->getId());
}
}
}

@ -1227,10 +1227,10 @@ class Exercise
$table = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION);
$sql = "SELECT q.id
$sql = "SELECT q.iid
FROM $table e
INNER JOIN $tableQuestion q
ON (e.question_id = q.id AND e.c_id = q.c_id)
ON (e.question_id = q.iid AND e.c_id = q.c_id)
WHERE
q.type = $type AND
e.c_id = {$this->course_id} AND
@ -2084,7 +2084,7 @@ class Exercise
'hide_question_score',
null,
get_lang('Hide question score')
),
),
$form->createElement(
'checkbox',
'hide_category_table',
@ -3541,7 +3541,7 @@ class Exercise
$questionName = $objQuestionTmp->selectTitle();
$questionWeighting = $objQuestionTmp->selectWeighting();
$answerType = $objQuestionTmp->selectType();
$quesId = $objQuestionTmp->selectId();
$quesId = $objQuestionTmp->getId();
$extra = $objQuestionTmp->extra;
$next = 1; //not for now
$totalWeighting = 0;
@ -5682,8 +5682,8 @@ class Exercise
$message .= '<p>'.$comment.'</p>';
echo $message;
$_SESSION['hotspot_delineation_result'][$this->selectId()][$questionId][0] = $message;
$_SESSION['hotspot_delineation_result'][$this->selectId()][$questionId][1] = $_SESSION['exerciseResultCoordinates'][$questionId];
$_SESSION['hotspot_delineation_result'][$this->getId()][$questionId][0] = $message;
$_SESSION['hotspot_delineation_result'][$this->selgetIdectId()][$questionId][1] = $_SESSION['exerciseResultCoordinates'][$questionId];
} else {
echo $hotspot_delineation_result[0];
}

@ -131,7 +131,7 @@ if (!empty($exerciseId)) {
$form = new FormValidator(
'exercise_admin',
'post',
api_get_self().'?'.api_get_cidreq().'&id='.$exerciseId
api_get_self().'?'.api_get_cidreq().'&exerciseId='.$exerciseId
);
$objExercise->read($exerciseId, false);
$form->addElement('hidden', 'edit', 'true');
@ -160,7 +160,7 @@ if ($form->validate()) {
}
$exercise_id = $objExercise->getId();
Session::erase('objExercise');
header('Location:admin.php?id='.$exercise_id.'&'.api_get_cidreq());
header('Location:admin.php?exerciseId='.$exercise_id.'&'.api_get_cidreq());
exit;
} else {
if (api_is_in_gradebook()) {
@ -175,7 +175,7 @@ if ($form->validate()) {
'name' => get_lang('Tests'),
];
$interbreadcrumb[] = [
'url' => 'admin.php?id='.$objExercise->getId().'&'.api_get_cidreq(),
'url' => 'admin.php?exerciseId='.$objExercise->getId().'&'.api_get_cidreq(),
'name' => $objExercise->selectTitle(true),
];

@ -2,7 +2,6 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\TrackEAttemptRecording;
/**

@ -110,7 +110,7 @@ if (api_is_course_admin() && !in_array($origin, ['learnpath', 'embeddable'])) {
]
);
}
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exe_id);
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exeId);
$learnpath_id = isset($exercise_stat_info['orig_lp_id']) ? $exercise_stat_info['orig_lp_id'] : 0;
$learnpath_item_id = isset($exercise_stat_info['orig_lp_item_id']) ? $exercise_stat_info['orig_lp_item_id'] : 0;
$learnpath_item_view_id = isset($exercise_stat_info['orig_lp_item_view_id'])
@ -165,7 +165,7 @@ $attempt_count = Event::get_attempt_count(
$learnpath_item_id,
$learnpath_item_view_id
);
if ($objExercise->selectAttempts() > 0) {
if ($attempt_count >= $objExercise->selectAttempts()) {
Display::addFlash(

@ -881,7 +881,7 @@ if (MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY != $answerType) {
$pluginEvaluation = QuestionOptionsEvaluationPlugin::create();
if ('true' === $pluginEvaluation->get(QuestionOptionsEvaluationPlugin::SETTING_ENABLE)) {
$formula = $pluginEvaluation->getFormulaForExercise($objExercise->selectId());
$formula = $pluginEvaluation->getFormulaForExercise($objExercise->getId());
if (!empty($formula)) {
$totalScore = $pluginEvaluation->getResultWithFormula($id, $formula);

@ -8,6 +8,7 @@ use ChamiloSession as Session;
* @author Julio Montoya <gugli100@gmail.com>
*/
require_once __DIR__.'/../inc/global.inc.php';
$current_course_tool = TOOL_QUIZ;
api_protect_course_script();
@ -36,7 +37,32 @@ $questionNum = (int) $_GET['num'];
$questionId = $questionList[$questionNum];
$choiceValue = isset($_GET['choice']) ? $_GET['choice'] : '';
$hotSpot = isset($_GET['hotspot']) ? $_GET['hotspot'] : '';
$tryAgain = isset($_GET['tryagain']) && 1 === (int) $_GET['tryagain'];
$allowTryAgain = false;
if ($tryAgain) {
// Check if try again exists in this question, otherwise only allow one attempt BT#15827.
$objQuestionTmp = Question::read($questionId);
$answerType = $objQuestionTmp->selectType();
$showResult = false;
$objAnswerTmp = new Answer($questionId, api_get_course_int_id());
$answers = $objAnswerTmp->getAnswers();
if (!empty($answers)) {
foreach ($answers as $answerData) {
if (isset($answerData['destination'])) {
$itemList = explode('@@', $answerData['destination']);
if (isset($itemList[0]) && !empty($itemList[0])) {
$allowTryAgain = true;
break;
}
}
}
}
}
$loaded = isset($_GET['loaded']);
if ($allowTryAgain) {
unset($exerciseResult[$questionId]);
}
if (empty($choiceValue) && isset($exerciseResult[$questionId])) {
$choiceValue = $exerciseResult[$questionId];
@ -54,6 +80,15 @@ if (!empty($choiceValue)) {
}
}
$header = '';
$exeId = 0;
if ($objExercise->getFeedbackType() === EXERCISE_FEEDBACK_TYPE_POPUP) {
$exeId = Session::read('exe_id');
$header = '
<div class="modal-header">
<h4 class="modal-title" id="global-modal-title">'.get_lang('Incorrect').'</h4>
</div>';
}
echo '<script>
function tryAgain() {
$(function () {
@ -63,7 +98,7 @@ function tryAgain() {
function SendEx(num) {
if (num == -1) {
window.location.href = "exercise_result.php?'.api_get_cidreq().'&take_session=1&exerciseId='.$exerciseId.'&num="+num+"&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
window.location.href = "exercise_result.php?'.api_get_cidreq().'&exe_id='.$exeId.'&take_session=1&exerciseId='.$exerciseId.'&num="+num+"&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
} else {
num -= 1;
window.location.href = "exercise_submit.php?'.api_get_cidreq().'&tryagain=1&exerciseId='.$exerciseId.'&num="+num+"&learnpath_item_id='.$learnpath_item_id.'&learnpath_id='.$learnpath_id.'";
@ -72,13 +107,6 @@ function SendEx(num) {
}
</script>';
$header = '';
if (EXERCISE_FEEDBACK_TYPE_POPUP === $objExercise->getFeedbackType()) {
$header = '
<div class="modal-header">
<h4 class="modal-title" id="global-modal-title">'.get_lang('Incorrect').'</h4>
</div>';
}
echo '<div id="delineation-container">';
// Getting the options by js
@ -169,6 +197,7 @@ $choice[$questionId] = isset($choiceValue) ? $choiceValue : null;
if (!is_array($exerciseResult)) {
$exerciseResult = [];
}
$saveResults = (int) $objExercise->getFeedbackType() == EXERCISE_FEEDBACK_TYPE_POPUP;
// if the user has answered at least one question
if (is_array($choice)) {
@ -232,12 +261,12 @@ switch ($answerType) {
ob_start();
$result = $objExercise->manage_answer(
0,
$exeId,
$questionId,
$choiceValue,
'exercise_result',
null,
false,
[],
$saveResults,
false,
$showResult,
null,

@ -177,7 +177,7 @@ function aiken_import_exercise($file)
$exercise = new Exercise();
$exercise->exercise = $exercise_info['name'];
$exercise->save();
$last_exercise_id = $exercise->selectId();
$last_exercise_id = $exercise->getId();
$tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION);
$tableAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
if (!empty($last_exercise_id)) {
@ -196,7 +196,7 @@ function aiken_import_exercise($file)
$type = $question->selectType();
$question->type = constant($type);
$question->save($exercise);
$last_question_id = $question->selectId();
$last_question_id = $question->getId();
// 3. Create answer
$answer = new Answer($last_question_id, $courseId, $exercise, false);

@ -162,7 +162,7 @@ function import_exercise($file)
}
$exercise->save();
$last_exercise_id = $exercise->selectId();
$last_exercise_id = $exercise->getId();
$courseId = api_get_course_int_id();
if (!empty($last_exercise_id)) {
// For each question found...
@ -210,7 +210,7 @@ function import_exercise($file)
$question->updateDescription($description);
$question->save($exercise);
$last_question_id = $question->selectId();
$last_question_id = $question->getId();
//3. Create answer
$answer = new Answer($last_question_id);
$answerList = $question_array['answer'];
@ -733,10 +733,10 @@ function qtiProcessManifest($filePath)
$specialHref = Database::escape_string(preg_replace('/_/', '-', strtolower($href)));
$specialHref = preg_replace('/(-){2,8}/', '-', $specialHref);
$sql = "SELECT iid FROM $tableDocuments
$sql = "SELECT iid FROM $tableDocuments
WHERE
c_id = ".$course['real_id']." AND
session_id = $sessionId AND
c_id = ".$course['real_id']." AND
session_id = $sessionId AND
path = '/".$specialHref."'";
$result = Database::query($sql);
$documentId = 0;

@ -168,9 +168,9 @@ class ImsSection
public function start_section()
{
return '<section
ident = "EXO_'.$this->exercise->selectId().'"
title = "'.cleanAttribute(formatExerciseQtiDescription($this->exercise->selectTitle())).'"
return '<section
ident = "EXO_'.$this->exercise->getId().'"
title = "'.cleanAttribute(formatExerciseQtiDescription($this->exercise->selectTitle())).'"
>'."\n";
}
@ -317,7 +317,7 @@ class ImsItem
{
$this->question = $question;
$this->answer = $question->answer;
$this->questionIdent = 'QST_'.$question->selectId();
$this->questionIdent = 'QST_'.$question->getId();
}
/**

@ -250,6 +250,10 @@ class FillBlanks extends Question
function changeBlankSeparator()
{
var definedSeparator = $("[name=select_separator] option:selected").text();
$("[name=select_separator] option").each(function (index, value) {
$("#defineoneblank").html($("#defineoneblank").html().replace($(value).html(), definedSeparator))
});
var separatorNumber = $("#select_separator").val();
var tabSeparator = getSeparatorFromNumber(separatorNumber);
blankSeparatorStart = tabSeparator[0];
@ -1127,18 +1131,6 @@ class FillBlanks extends Question
$result = '';
$listStudentAnswerInfo = self::getAnswerInfo($answer, true);
/*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;
}
}*/
// rebuild the answer with good HTML style
// this is the student answer, right or wrong
for ($i = 0; $i < count($listStudentAnswerInfo['student_answer']); $i++) {
@ -1163,6 +1155,11 @@ class FillBlanks extends Question
// rebuild the sentence with student answer inserted
for ($i = 0; $i < count($listStudentAnswerInfo['common_words']); $i++) {
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK) {
if (empty($listStudentAnswerInfo['student_answer'][$i])) {
continue;
}
}
$result .= isset($listStudentAnswerInfo['common_words'][$i]) ? $listStudentAnswerInfo['common_words'][$i] : '';
$studentLabel = isset($listStudentAnswerInfo['student_answer'][$i]) ? $listStudentAnswerInfo['student_answer'][$i] : '';
$result .= $studentLabel;
@ -1209,6 +1206,7 @@ class FillBlanks extends Question
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_NO_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
$hideExpectedAnswer = true;
if ($showTotalScoreAndUserChoices) {
@ -1318,6 +1316,9 @@ class FillBlanks extends Question
$resultsDisabled = false,
$showTotalScoreAndUserChoices = false
) {
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK) {
return '';
}
return self::getHtmlAnswer(
$answer,
$correct,

@ -24,6 +24,9 @@ $userId = api_get_user_id();
$courseId = api_get_course_int_id();
$objExercise = new Exercise($courseId);
$debug = false;
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
@ -94,10 +97,12 @@ $data['image_height'] = $pictureHeight;
$data['courseCode'] = $_course['path'];
$data['hotspots'] = [];
$resultDisable = $objExercise->selectResultsDisabled();
$showTotalScoreAndUserChoicesInLastAttempt = true;
if (in_array(
$objExercise->selectResultsDisabled(), [
$resultDisable, [
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
)
@ -128,14 +133,14 @@ if (in_array(
}
$hideExpectedAnswer = false;
if (0 == $objExercise->getFeedbackType() &&
RESULT_DISABLE_SHOW_SCORE_ONLY == $objExercise->selectResultsDisabled()
if ($objExercise->getFeedbackType() == 0 &&
$resultDisable == RESULT_DISABLE_SHOW_SCORE_ONLY
) {
$hideExpectedAnswer = true;
}
if (in_array(
$objExercise->selectResultsDisabled(), [
$resultDisable, [
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
]
@ -144,6 +149,36 @@ if (in_array(
$hideExpectedAnswer = $showTotalScoreAndUserChoicesInLastAttempt ? false : true;
}
if (in_array(
$resultDisable, [
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK,
]
)
) {
$hideExpectedAnswer = false;
}
$hotSpotWithAnswer = [];
$data['answers'] = [];
$rs = $em
->getRepository('ChamiloCoreBundle:TrackEHotspot')
->findBy(
[
'hotspotQuestionId' => $questionId,
'cId' => $courseId,
'hotspotExeId' => $exeId,
],
['hotspotAnswerId' => 'ASC']
);
/** @var TrackEHotspot $row */
foreach ($rs as $row) {
$data['answers'][] = $row->getHotspotCoordinate();
if ($row->getHotspotCorrect()) {
$hotSpotWithAnswer[] = $row->getHotspotAnswerId();
}
}
if (!$hideExpectedAnswer) {
$qb = $em->createQueryBuilder();
$qb
@ -165,8 +200,15 @@ if (!$hideExpectedAnswer) {
$result = $qb->getQuery()->getResult();
/** @var CQuizAnswer $hotSpotAnswer */
foreach ($result as $hotSpotAnswer) {
if (RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK == $resultDisable) {
if (false === $showTotalScoreAndUserChoicesInLastAttempt) {
if (!in_array($hotSpotAnswer->getIid(), $hotSpotWithAnswer)) {
continue;
}
}
}
/** @var CQuizAnswer $hotSpotAnswer */
$hotSpot = [];
$hotSpot['id'] = $hotSpotAnswer->getIid();
$hotSpot['answer'] = $hotSpotAnswer->getAnswer();

@ -19,7 +19,7 @@ $courseCode = $_GET['coursecode'];
$questionId = $_GET['questionId'];
$coordinates = $_GET['coord'];
$objExercise = Session::read('objExercise');
$exerciseId = $objExercise->selectId();
$exerciseId = $objExercise->getId();
// Save clicking order
$answerOrderId = count($_SESSION['exerciseResult'][$questionId]['ids']) + 1;
if ('0' == $_GET['answerId']) {

@ -20,7 +20,7 @@ $questionId = $_GET['questionId'];
$coordinates = $_GET['coord'];
$objExercise = Session::read('objExercise');
$hotspotId = $_GET['hotspotId'];
$exerciseId = $objExercise->selectId();
$exerciseId = $objExercise->getId();
if ('0' == $_GET['answerId']) { // click is NOT on a hotspot
$hit = 0;
$answerId = $hotspotId;
@ -48,8 +48,8 @@ $TBL_TRACK_E_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT)
// update db
$update_id = $_SESSION['exerciseResult'][$questionId]['ids'][$answerId];
$sql = "UPDATE $TBL_TRACK_E_HOTSPOT
$sql = "UPDATE $TBL_TRACK_E_HOTSPOT
SET coordinate = '".Database::escape_string($coordinates)."'
WHERE id = ".(int) $update_id.'
WHERE id = ".(int) $update_id.'
LIMIT 1';
$result = Database::query($sql);

@ -24,7 +24,7 @@ $interbreadcrumb[] = [
'name' => get_lang('Tests'),
];
$interbreadcrumb[] = [
'url' => "admin.php?id=$exercise_id&".api_get_cidreq(),
'url' => "admin.php?exerciseId=$exercise_id&".api_get_cidreq(),
'name' => $objExercise->selectTitle(true),
];
@ -108,7 +108,7 @@ $(function() {
</script>
<?php
$actions = '<a href="exercise_report.php?id='.(int) ($_GET['exerciseId']).'&'.api_get_cidreq().'">'.
$actions = '<a href="exercise_report.php?exerciseId='.(int) ($_GET['exerciseId']).'&'.api_get_cidreq().'">'.
Display::return_icon('back.png', get_lang('Go back to the questions list'), '', ICON_SIZE_MEDIUM).'</a>';
echo $actions = Display::div($actions, ['class' => 'actions']);

@ -235,7 +235,9 @@ class MultipleAnswer extends Question
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
if (false === $exercise->hideComment) {
$header .= '<th>'.get_lang('Comment').'</th>';
}
$header .= '</tr>';
return $header;

@ -236,7 +236,9 @@ class MultipleAnswerCombination extends Question
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
if (false === $exercise->hideComment) {
$header .= '<th>'.get_lang('Comment').'</th>';
}
$header .= '</tr>';
return $header;

@ -117,7 +117,11 @@ class MultipleAnswerTrueFalse extends Question
$j = 1;
if (!empty($optionData)) {
foreach ($optionData as $id => $data) {
$form->addElement('radio', 'correct['.$i.']', null, null, $id);
$rdoCorrect = $form->addElement('radio', 'correct['.$i.']', null, null, $id);
if (isset($_POST['correct']) && isset($_POST['correct'][$i]) && $id == $_POST['correct'][$i]) {
$rdoCorrect->setValue(Security::remove_XSS($_POST['correct'][$i]));
}
$j++;
if (3 == $j) {
break;
@ -141,6 +145,9 @@ class MultipleAnswerTrueFalse extends Question
['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']
);
if (isset($_POST['answer']) && isset($_POST['answer'][$i])) {
$form->getElement("answer[$i]")->setValue(Security::remove_XSS($_POST['answer'][$i]));
}
// show comment when feedback is enable
if (EXERCISE_FEEDBACK_TYPE_EXAM != $obj_ex->getFeedbackType()) {
$form->addElement(
@ -154,6 +161,9 @@ class MultipleAnswerTrueFalse extends Question
'Height' => '100',
]
);
if (isset($_POST['comment']) && isset($_POST['comment'][$i])) {
$txtComment->setValue(Security::remove_XSS($_POST['comment'][$i]));
}
}
$form->addHtml('</tr>');
@ -206,9 +216,9 @@ class MultipleAnswerTrueFalse extends Question
$scores = explode(':', $this->extra);
if (!empty($scores)) {
for ($i = 1; $i <= 3; $i++) {
$defaults['option['.$i.']'] = $scores[$i - 1];
}
$txtOption1->setValue($scores[0]);
$txtOption2->setValue($scores[1]);
$txtOption3->setValue($scores[2]);
}
}
@ -224,9 +234,7 @@ class MultipleAnswerTrueFalse extends Question
$form->addGroup($buttonGroup);
}
if (!empty($this->id)) {
$form->setDefaults($defaults);
} else {
if (!empty($this->id) && !$form->isSubmitted()) {
$form->setDefaults($defaults);
}
$form->setConstants(['nb_answers' => $nb_answers]);
@ -327,7 +335,9 @@ class MultipleAnswerTrueFalse extends Question
]
)
) {
$header .= '<th>'.get_lang('Comment').'</th>';
if (false === $exercise->hideComment) {
$header .= '<th>'.get_lang('Comment').'</th>';
}
}
$header .= '</tr>';

@ -10,7 +10,9 @@
require_once __DIR__.'/../inc/global.inc.php';
// Clear the exercise session just in case
$current_course_tool = TOOL_QUIZ;
Exercise::cleanSessionVariables();
$this_section = SECTION_COURSES;
$js = '<script>'.api_get_language_translate_html().'</script>';
$htmlHeadXtra[] = $js;
@ -19,7 +21,7 @@ $htmlHeadXtra[] = $js;
api_protect_course_script(true);
$sessionId = api_get_session_id();
$courseCode = api_get_course_id();
$exercise_id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
$exercise_id = isset($_REQUEST['exerciseId']) ? (int) $_REQUEST['exerciseId'] : 0;
$objExercise = new Exercise();
$result = $objExercise->read($exercise_id, true);
@ -28,15 +30,21 @@ if (!$result) {
api_not_allowed(true);
}
$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;
$learnpathItemViewId = isset($_REQUEST['learnpath_item_view_id']) ? (int) ($_REQUEST['learnpath_item_view_id']) : null;
if ('true' === api_get_plugin_setting('positioning', 'tool_enable')) {
$plugin = Positioning::create();
if ($plugin->blockFinalExercise(api_get_user_id(), $exercise_id, api_get_course_int_id(), $sessionId)) {
api_not_allowed(true);
}
}
$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;
$learnpathItemViewId = isset($_REQUEST['learnpath_item_view_id']) ? (int) $_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'] : '',
];
@ -96,12 +104,12 @@ if ($is_allowed_to_edit) {
if ($objExercise->sessionId == $sessionId) {
$editLink = Display::url(
Display::return_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL),
api_get_path(WEB_CODE_PATH).'exercise/admin.php?'.api_get_cidreq().'&id='.$objExercise->id
api_get_path(WEB_CODE_PATH).'exercise/admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id
);
}
$editLink .= Display::url(
Display::return_icon('test_results.png', get_lang('Results and feedback and feedback'), [], ICON_SIZE_SMALL),
api_get_path(WEB_CODE_PATH).'exercise/exercise_report.php?'.api_get_cidreq().'&id='.$objExercise->id,
api_get_path(WEB_CODE_PATH).'exercise/exercise_report.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id,
['title' => get_lang('Results and feedback and feedback')]
);
}
@ -218,6 +226,7 @@ if (in_array(
$objExercise->results_disabled,
[
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
])
) {
@ -280,6 +289,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_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
RESULT_DISABLE_RANKING,
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
@ -295,6 +305,7 @@ if (!empty($attempts)) {
RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
RESULT_DISABLE_SHOW_FINAL_SCORE_ONLY_WITH_CATEGORIES,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT,
RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK,
RESULT_DISABLE_DONT_SHOW_SCORE_ONLY_IF_USER_FINISHES_ATTEMPTS_SHOW_ALWAYS_FEEDBACK,
RESULT_DISABLE_RANKING,
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
@ -347,6 +358,7 @@ if (!empty($attempts)) {
}
break;
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT:
if ($blockShowAnswers) {
$header_names = [get_lang('Attempt'), get_lang('Start Date'), get_lang('IP'), get_lang('Score')];

@ -109,6 +109,11 @@ abstract class Question
];
}
public function getId()
{
return $this->iid;
}
/**
* @return int|null
*/
@ -214,18 +219,6 @@ abstract class Question
return false;
}
/**
* returns the question ID.
*
* @author Olivier Brouckaert
*
* @return int - question ID
*/
public function selectId()
{
return $this->id;
}
/**
* returns the question title.
*
@ -395,9 +388,15 @@ abstract class Question
c_id = ".$courseId;
$res = Database::query($sql);
$row = Database::fetch_array($res);
$allowMandatory = api_get_configuration_value('allow_mandatory_question_in_category');
if ($row['nb'] > 0) {
$extraMandatoryCondition = '';
if ($allowMandatory) {
$extraMandatoryCondition = ", mandatory = {$this->mandatory}";
}
$sql = "UPDATE $table
SET category_id = $categoryId
$extraMandatoryCondition
WHERE
question_id = $question_id ";
Database::query($sql);
@ -405,6 +404,14 @@ abstract class Question
$sql = "INSERT INTO $table (question_id, category_id)
VALUES ($question_id, $categoryId)";
Database::query($sql);
if ($allowMandatory) {
$id = Database::insert_id();
if ($id) {
$sql = "UPDATE $table SET mandatory = {$this->mandatory}
WHERE iid = $id";
Database::query($sql);
}
}
}
return true;
@ -1537,7 +1544,7 @@ abstract class Question
$explanation = $type->getExplanation();
echo '<li>';
echo '<div class="icon-image">';
$icon = '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes&answerType='.$i.'&id='.$exerciseId.'">'.
$icon = '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes&answerType='.$i.'&exerciseId='.$exerciseId.'">'.
Display::return_icon($img, $explanation, null, ICON_SIZE_BIG).'</a>';
if (false === $objExercise->force_edit_exercise_in_lp) {

@ -61,13 +61,13 @@ if (is_object($objQuestion)) {
if (isset($_GET['editQuestion'])) {
if (empty($exerciseId)) {
Display::addFlash(Display::return_message(get_lang('Item updated')));
$url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?id='.$exerciseId.'&'.api_get_cidreq().'&editQuestion='.$objQuestion->id;
$url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&editQuestion='.$objQuestion->id;
header("Location: $url");
exit;
}
Display::addFlash(Display::return_message(get_lang('Item updated')));
$url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?id='.$exerciseId.'&'.api_get_cidreq().'&page='.$page;
$url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&page='.$page;
header("Location: $url");
exit;
} else {
@ -78,12 +78,12 @@ if (is_object($objQuestion)) {
$page = round($objExercise->getQuestionCount() / $length);
}
Display::addFlash(Display::return_message(get_lang('Item added')));
$url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?id='.$exerciseId.'&'.api_get_cidreq().'&page='.$page;
$url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'&page='.$page;
header("Location: $url");
exit;
}
} else {
echo '<script type="text/javascript">window.location.href="admin.php?id='.$exerciseId.'&page='.$page.'&hotspotadmin='.$objQuestion->id.'&'.api_get_cidreq().'"</script>';
echo '<script type="text/javascript">window.location.href="admin.php?exerciseId='.$exerciseId.'&page='.$page.'&hotspotadmin='.$objQuestion->id.'&'.api_get_cidreq().'"</script>';
}
} else {
if (isset($questionName)) {

@ -94,7 +94,7 @@ if ($form->validate()) {
header('Location: question_create.php?'.api_get_cidreq().'&error=true');
exit;
}
header('Location: admin.php?id='.$values['exercise'].'&newQuestion=yes&isContent='.$values['is_content'].'&answerType='.$answer_type);
header('Location: admin.php?exerciseId='.$values['exercise'].'&newQuestion=yes&isContent='.$values['is_content'].'&answerType='.$answer_type);
exit;
} else {
// header

@ -161,6 +161,7 @@ if (!$inATest) {
// In the building exercise mode show question list ordered as is.
$objExercise->setCategoriesGrouping(false);
$originalQuestionSelectType = $objExercise->questionSelectionType;
// In building mode show all questions not render by teacher order.
$objExercise->questionSelectionType = EX_Q_SELECTION_ORDERED;
$allowQuestionOrdering = true;
@ -195,6 +196,7 @@ if (!$inATest) {
// Classic order
$questionList = $objExercise->selectQuestionList(true, true);
}
$objExercise->questionSelectionType = $originalQuestionSelectType;
echo '
<div class="row hidden-xs">
@ -285,7 +287,7 @@ if (!$inATest) {
$delete_link = '';
}
$btnDetail = implode(
$btnActions = implode(
PHP_EOL,
[$edit_link, $clone_link, $delete_link]
);
@ -310,7 +312,7 @@ if (!$inATest) {
// Question category
$questionCategory = Security::remove_XSS(
TestCategory::getCategoryNameForQuestion($objQuestionTmp->id)
TestCategory::getCategoryNameForQuestion($objQuestionTmp->getId())
);
if (empty($questionCategory)) {
$questionCategory = '-';
@ -327,7 +329,7 @@ if (!$inATest) {
$questionScore = $objQuestionTmp->selectWeighting();
echo '<div id="question_id_list_'.$id.'">
<div class="header_operations" data-exercise="'.$objExercise->selectId().'"
<div class="header_operations" data-exercise="'.$objExercise->getId().'"
data-question="'.$id.'">
<div class="row">
<div class="question col-sm-5 col-xs-12">'
@ -350,7 +352,7 @@ if (!$inATest) {
.$questionScore.'
</div>
<div class="btn-actions text-right col-sm-2 col-xs-6">
<div class="edition">'.$btnDetail.'</div>
<div class="edition">'.$btnActions.'</div>
</div>
</div>
</div>

@ -55,7 +55,7 @@ $interbreadcrumb[] = ['url' => 'exercise.php?'.api_get_cidreq(), 'name' => get_l
if (!empty($objExercise->id)) {
$interbreadcrumb[] = [
'url' => 'admin.php?id='.$objExercise->id.'&'.api_get_cidreq(),
'url' => 'admin.php?exerciseId='.$objExercise->id.'&'.api_get_cidreq(),
'name' => $objExercise->selectTitle(true),
];
}
@ -305,7 +305,7 @@ if (isset($fromExercise) && $fromExercise > 0) {
} else {
echo '<a href="exercise.php?'.api_get_cidreq().'">'.
Display::return_icon('back.png', get_lang('BackToTestsList'), '', ICON_SIZE_MEDIUM).'</a>';
echo "<a href='admin.php?id=0'>".
echo "<a href='admin.php?exerciseId=0'>".
Display::return_icon('add_question.gif', get_lang('New question'), '', ICON_SIZE_MEDIUM).'</a>';
$titleAdd = get_lang('Manage all questions');
}
@ -1063,7 +1063,7 @@ echo '<input type="hidden" name="selected_course" value="'.$selected_course.'">'
echo '<input type="hidden" name="course_id" value="'.$selected_course.'">';
echo '<input type="hidden" name="action">';
$table = new HTML_Table(['class' => 'table table-bordered data_table'], false);
$table = new HTML_Table(['class' => 'table table-hover table-striped table-bordered data_table'], false);
$row = 0;
$column = 0;
foreach ($headers as $header) {

@ -10,15 +10,16 @@ use ChamiloSession as Session;
* @author Julio Montoya - Simple exercise result page
*/
require_once __DIR__.'/../inc/global.inc.php';
$current_course_tool = TOOL_QUIZ;
$id = isset($_REQUEST['id']) ? (int) $_GET['id'] : 0; // exe id
$show_headers = isset($_REQUEST['show_headers']) ? (int) $_REQUEST['show_headers'] : null;
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
$origin = api_get_origin();
if (in_array($origin, ['learnpath', 'embeddable', 'mobileapp'])) {
$show_headers = false;
}
$is_courseTutor = api_is_course_tutor();
api_protect_course_script($show_headers);
@ -37,7 +38,7 @@ if (empty($track_exercise_info)) {
}
$exercise_id = $track_exercise_info['exe_exo_id'];
$student_id = $track_exercise_info['exe_user_id'];
$student_id = (int) $track_exercise_info['exe_user_id'];
$current_user_id = api_get_user_id();
$objExercise = new Exercise();
@ -56,6 +57,15 @@ if (!$is_allowedToEdit) {
}
}
$allowSignature = false;
if ($student_id === $current_user_id && ExerciseSignaturePlugin::exerciseHasSignatureActivated($objExercise)) {
// Check if signature exists.
$signature = ExerciseSignaturePlugin::getSignature($current_user_id, $track_exercise_info);
if (false === $signature) {
$allowSignature = true;
}
}
$htmlHeadXtra[] = '<link rel="stylesheet" href="'.api_get_path(WEB_LIBRARY_JS_PATH).'hotspot/css/hotspot.css">';
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'hotspot/js/hotspot.js"></script>';
//$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_JS_PATH).'annotation/js/annotation.js"></script>';
@ -92,20 +102,73 @@ if ($show_headers) {
$message = Session::read('attempt_remaining');
Session::erase('attempt_remaining');
$allowExportPdf = api_get_configuration_value('quiz_results_answers_report');
ob_start();
ExerciseLib::displayQuestionListByAttempt(
$stats = ExerciseLib::displayQuestionListByAttempt(
$objExercise,
$id,
false,
$message
$message,
$allowSignature,
$allowExportPdf,
'export' === $action
);
$pageContent = ob_get_contents();
ob_end_clean();
switch ($action) {
case 'export':
if ($allowExportPdf) {
$allAnswers = $stats['all_answers_html'];
@$pdf = new PDF();
$cssFile = api_get_path(SYS_CSS_PATH).'themes/chamilo/default.css';
$title = get_lang('ResponseReport');
$exerciseTitle = $objExercise->get_formated_title();
$studentInfo = api_get_user_info($student_id);
$userHeader = $objExercise->showExerciseResultHeader(
$studentInfo,
$track_exercise_info,
false,
false,
false
);
$filename = get_lang('Exercise').'_'.$exerciseTitle;
$pdf->content_to_pdf("
<html><body>
<h2 style='text-align: center'>$title</h2>
$userHeader
$allAnswers
</body></html>",
file_get_contents($cssFile),
$filename,
api_get_course_id(),
'D',
false,
null,
false,
true
);
} else {
api_not_allowed(true);
}
exit;
break;
}
$pageBottom = '<div class="question-return">';
$pageBottom .= Display::url(
get_lang('BackToAttemptList'),
api_get_path(WEB_CODE_PATH).'exercise/overview.php?exerciseId='.$exercise_id.'&'.api_get_cidreq(),
['class' => 'btn btn-primary']
);
$pageBottom .= '</div>';
$pageContent .= $pageBottom;
$template = new Template('', $show_headers, $show_headers);
$template->assign('page_top', '');
$template->assign('page_bottom', '');
$template->assign('page_content', $pageContent);
$template->assign('allow_signature', $allowSignature);
$template->assign('exe_id', $id);
$layout = $template->fetch($template->get_template('exercise/result.tpl'));
$template->assign('content', $layout);
$template->display_one_col_template();

@ -4,6 +4,7 @@
require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_COURSES;
api_protect_course_script(true, false, true);
$showPage = false;
@ -98,7 +99,7 @@ if (!empty($question_list)) {
}
// Format A table
$table = new HTML_Table(['class' => 'data_table']);
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
$row = 0;
$column = 0;
foreach ($headers as $header) {
@ -136,7 +137,8 @@ if (!empty($question_list)) {
$question_id,
$exerciseId,
$courseCode,
$sessionId
$sessionId,
true
);
$answer = new Answer($question_id);
@ -285,7 +287,7 @@ if (!empty($question_list)) {
}
// Format A table
$table = new HTML_Table(['class' => 'data_table']);
$table = new HTML_Table(['class' => 'table table-hover table-striped data_table']);
$row = 0;
$column = 0;
foreach ($headers as $header) {
@ -304,18 +306,32 @@ foreach ($data as $row_table) {
$row++;
}
$content .= $table->toHtml();
$exportPdf = isset($_GET['export_pdf']) && !empty($_GET['export_pdf']) ? (int) $_GET['export_pdf'] : 0;
if ($exportPdf) {
$fileName = get_lang('Report').'_'.api_get_course_id().'_'.api_get_local_time();
$params = [
'filename' => $fileName,
'pdf_title' => $objExercise->selectTitle(true).'<br>'.get_lang('ReportByQuestion'),
'pdf_description' => get_lang('Report'),
'format' => 'A4',
'orientation' => 'P',
];
Export::export_html_to_pdf($content, $params);
exit;
}
$interbreadcrumb[] = [
'url' => 'exercise.php?'.api_get_cidreq(),
'name' => get_lang('Tests'),
];
$interbreadcrumb[] = [
'url' => "admin.php?id=$exerciseId&".api_get_cidreq(),
'url' => "admin.php?exerciseId=$exerciseId&".api_get_cidreq(),
'name' => $objExercise->selectTitle(true),
];
$tpl = new Template(get_lang('Report by question'));
$actions = '<a href="exercise_report.php?id='.$exerciseId.'&'.api_get_cidreq().'">'.
$actions = '<a href="exercise_report.php?exerciseId='.$exerciseId.'&'.api_get_cidreq().'">'.
Display:: return_icon(
'back.png',
get_lang('Go back to the questions list'),
@ -323,6 +339,10 @@ $actions = '<a href="exercise_report.php?id='.$exerciseId.'&'.api_get_cidreq().'
ICON_SIZE_MEDIUM
)
.'</a>';
$actions .= Display::url(
Display::return_icon('pdf.png', get_lang('ExportToPDF'), [], ICON_SIZE_MEDIUM),
'stats.php?exerciseId='.$exerciseId.'&export_pdf=1&'.api_get_cidreq()
);
$actions = Display::div($actions, ['class' => 'actions']);
$content = $actions.$content;
$tpl->assign('content', $content);

@ -24,6 +24,7 @@ $nameTools = '';
require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_COURSES;
api_protect_course_script(true);
if (!api_is_allowed_to_edit()) {

@ -452,7 +452,9 @@ class UniqueAnswer extends Question
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
if (false === $exercise->hideComment) {
$header .= '<th>'.get_lang('Comment').'</th>';
}
$header .= '</tr>';
return $header;

@ -409,7 +409,9 @@ class UniqueAnswerNoOption extends Question
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
if (false === $exercise->hideComment) {
$header .= '<th>'.get_lang('Comment').'</th>';
}
$header .= '</tr>';
return $header;

@ -7,16 +7,19 @@ use ChamiloSession as Session;
/**
* Upload quiz: This script shows the upload quiz feature.
*/
$help_content = 'exercise_upload';
require_once __DIR__.'/../inc/global.inc.php';
api_protect_course_script(true);
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
$debug = false;
$origin = api_get_origin();
if (!$is_allowed_to_edit) {
api_not_allowed(true);
}
$this_section = SECTION_COURSES;
$htmlHeadXtra[] = "<script>
$(function(){
$('#user_custom_score').click(function() {
@ -434,8 +437,9 @@ function lp_upload_quiz_action_handling()
$score,
$id
);
$total += (float) $score;
if ($correct) {
$total += (float) $score;
}
$id++;
}
@ -558,6 +562,7 @@ function lp_upload_quiz_action_handling()
}
}
}
Display::addFlash(Display::return_message(get_lang('FileImported')));
if (isset($_SESSION['oLP']) && isset($_GET['lp_id'])) {
$previous = $_SESSION['oLP']->select_previous_item_id();
@ -576,8 +581,9 @@ function lp_upload_quiz_action_handling()
exit;
} else {
// header('location: exercise.php?' . api_get_cidreq());
echo '<script>window.location.href = "'.api_get_path(WEB_CODE_PATH).'exercise/admin.php?'.api_get_cidreq().'&exerciseId='.$quiz_id.'&session_id='.api_get_session_id().'"</script>';
}
$exerciseUrl = api_get_path(WEB_CODE_PATH).
'exercise/admin.php?'.api_get_cidreq().'&exerciseId='.$quiz_id.'&session_id='.api_get_session_id();
api_location($exerciseUrl);
}
}

@ -584,9 +584,9 @@ switch ($action) {
// This variable came from exercise_submit_modal.php.
$hotspot_delineation_result = null;
if (isset($_SESSION['hotspot_delineation_result']) &&
isset($_SESSION['hotspot_delineation_result'][$objExercise->selectId()])
isset($_SESSION['hotspot_delineation_result'][$objExercise->getId()])
) {
$hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->selectId()][$my_question_id];
$hotspot_delineation_result = $_SESSION['hotspot_delineation_result'][$objExercise->getId()][$my_question_id];
}
if ('simple' === $type) {
@ -710,7 +710,7 @@ switch ($action) {
Session::write('duration_time', [$key => $now]);
Event::updateEventExercise(
$exeId,
$objExercise->selectId(),
$objExercise->getId(),
$total_score,
$total_weight,
$session_id,

@ -474,6 +474,7 @@ define('RESULT_DISABLE_RANKING', 6);
define('RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER', 7);
define('RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING', 8);
define('RESULT_DISABLE_RADAR', 9);
define('RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK', 10);
define('EXERCISE_MAX_NAME_SIZE', 80);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,16 +1,6 @@
<?php
/* See license terms in /license.txt */
/**
* EVENTS LIBRARY.
*
* This is the events library for Chamilo.
* Functions of this library are used to record informations when some kind
* of event occur. Each event has his own types of informations then each event
* use its own function.
*
* @todo convert queries to use Database API
*/
class ExerciseShowFunctions
{
/**
@ -207,6 +197,7 @@ class ExerciseShowFunctions
* @param bool $showTotalScoreAndUserChoices
*/
public static function display_hotspot_answer(
$exercise,
$feedback_type,
$answerId,
$answer,
@ -230,9 +221,25 @@ class ExerciseShowFunctions
$hide_expected_answer = false;
}
break;
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
}
if (false === $showTotalScoreAndUserChoices && empty($studentChoice)) {
return '';
}
break;
}
$hotspot_colors = [
if (!$hide_expected_answer
&& !$studentChoice
&& in_array($resultsDisabled, [RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER])
) {
return;
}
$hotspotColors = [
'', // $i starts from 1 on next loop (ugly fix)
'#4271B5',
'#FE8E16',
@ -249,39 +256,38 @@ class ExerciseShowFunctions
'#F7BDE2',
];
$content = '<table class="data_table"><tr>';
$content = '<tr>';
$content .= '<td class="text-center" width="5%">';
$content .= '<span class="fa fa-square fa-fw fa-2x" aria-hidden="true" style="color:'.
$hotspot_colors[$orderColor].'"></span>';
$hotspotColors[$orderColor].'"></span>';
$content .= '</td>';
$content .= '<td class="text-left" width="25%">';
$content .= "$answerId - $answer";
$content .= '</td>';
if (false === $exercise->hideComment) {
$content .= '<td class="text-left" width="10%">';
if (!$hide_expected_answer) {
$status = Display::label(get_lang('Incorrect'), 'danger');
if ($studentChoice) {
$status = Display::label(get_lang('Correct'), 'success');
} else {
if (in_array($resultsDisabled, [
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
])
) {
return '';
}
}
$content .= $status;
} else {
$content .= '&nbsp;';
}
$content .= '</td>';
if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedback_type) {
$content .= '<td class="text-left" width="60%">';
if ($studentChoice) {
$content .= '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
} else {
$content .= '&nbsp;';
}
$content .= '</td>';
} else {
$content .= '<td class="text-left" width="60%">&nbsp;</td>';
}
}
$content .= '</tr>';
echo $content;
@ -319,6 +325,9 @@ class ExerciseShowFunctions
$showTotalScoreAndUserChoices,
$export = false
) {
if (true === $exercise->hideNoAnswer && empty($studentChoice)) {
return '';
}
if ($export) {
$answer = strip_tags_blacklist($answer, ['title', 'head']);
// Fix answers that contains this tags
@ -356,6 +365,11 @@ class ExerciseShowFunctions
$hide_expected_answer = false;
}
break;
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
if (false === $showTotalScoreAndUserChoices && empty($studentChoiceInt)) {
return '';
}
break;
}
$icon = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
@ -418,6 +432,7 @@ class ExerciseShowFunctions
$showComment = true;
}
if (false === $exercise->hideComment) {
if ($showComment) {
echo '<td width="20%">';
$color = 'black';
@ -435,6 +450,7 @@ class ExerciseShowFunctions
} else {
echo '<td>&nbsp;</td>';
}
}
echo '</tr>';
}
@ -486,6 +502,11 @@ class ExerciseShowFunctions
$hide_expected_answer = false;
}
break;
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
if (false === $showTotalScoreAndUserChoices && empty($studentChoice)) {
return '';
}
break;
}
$content = '<tr>';
@ -531,6 +552,7 @@ class ExerciseShowFunctions
$content .= '</td>';
}
if (false === $exercise->hideComment) {
if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
$content .= '<td width="20%">';
$color = 'black';
@ -553,6 +575,7 @@ class ExerciseShowFunctions
}
$content .= '</td>';
}
}
$content .= '</tr>';
echo $content;
@ -645,6 +668,7 @@ class ExerciseShowFunctions
'</div>
</td>';
if (false === $exercise->hideComment) {
if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
echo '<td width="20%">';
if (isset($newOptions[$studentChoice])) {
@ -654,6 +678,7 @@ class ExerciseShowFunctions
} else {
echo '<td>&nbsp;</td>';
}
}
echo '</tr>';
}
@ -704,6 +729,11 @@ class ExerciseShowFunctions
$hide_expected_answer = false;
}
break;
case RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT_NO_FEEDBACK:
if (false === $showTotalScoreAndUserChoices && empty($studentChoice)) {
return '';
}
break;
}
echo '<tr>';
@ -750,13 +780,17 @@ class ExerciseShowFunctions
echo '</td>';
}
if (false === $exercise->hideComment) {
if (EXERCISE_FEEDBACK_TYPE_EXAM != $feedbackType) {
echo '<td width="20%">';
//@todo replace this harcoded value
if ($studentChoice || in_array($resultsDisabled, [
if ($studentChoice || in_array(
$resultsDisabled,
[
RESULT_DISABLE_SHOW_ONLY_IN_CORRECT_ANSWER,
RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS_AND_RANKING,
])
]
)
) {
$color = 'black';
if ($studentChoice == $answerCorrect) {
@ -770,6 +804,7 @@ class ExerciseShowFunctions
echo '</td>';
} else {
echo '<td>&nbsp;</td>';
}
}
echo '</tr>';
}

@ -118,13 +118,14 @@ class TrackEAttempt
/**
* @var int
*
* @ORM\Column(name="second_spent", type="integer")
* @ORM\Column(name="seconds_spent", type="integer")
*/
protected $secondSpent;
protected $secondsSpent;
public function __construct()
{
$this->secondSpent = 0;
$this->teacherComment = '';
$this->secondsSpent = 0;
}
/**
@ -352,4 +353,16 @@ class TrackEAttempt
{
return $this->id;
}
public function getSecondsSpent(): int
{
return $this->secondsSpent;
}
public function setSecondsSpent(int $secondsSpent): TrackEAttempt
{
$this->secondsSpent = $secondsSpent;
return $this;
}
}

@ -269,4 +269,23 @@ class TrackEAttemptRecording
{
return $this->id;
}
/**
* @return int
*/
public function getAnswer()
{
return $this->answer;
}
/**
* @param int $answer
*/
public function setAnswer($answer): self
{
$this->answer = $answer;
return $this;
}
}

@ -97,8 +97,8 @@ class Version20180904175500 extends AbstractMigrationChamilo
$this->addSql('CREATE INDEX idx_track_e_attempt_tms ON track_e_attempt (tms)');
}
if (false === $table->hasColumn('second_spent')) {
$this->addSql('ALTER TABLE track_e_attempt ADD second_spent INT NOT NULL, CHANGE user_id user_id INT DEFAULT NULL');
if (false === $table->hasColumn('seconds_spent')) {
$this->addSql('ALTER TABLE track_e_attempt ADD seconds_spent INT NOT NULL, CHANGE user_id user_id INT DEFAULT NULL');
}
if (false === $table->hasForeignKey('FK_A89CC3B691D79BD3')) {

Loading…
Cancel
Save