Add setting "show_exercise_expected_choice" BT#13950

Show more information when resolving an exercise
pull/2458/head
jmontoyaa 8 years ago
parent fdc9332dfb
commit 531f5aa24e
  1. 44
      app/Resources/public/css/base.css
  2. 15
      main/exercise/Draggable.php
  3. 1
      main/exercise/Hpdownload.php
  4. 17
      main/exercise/MatchingDraggable.php
  5. 52
      main/exercise/TestCategory.php
  6. 24
      main/exercise/UniqueAnswerImage.php
  7. 37
      main/exercise/admin.php
  8. 10
      main/exercise/answer.class.php
  9. 13
      main/exercise/calculated_answer.class.php
  10. 1
      main/exercise/evalmathnotation.php
  11. 268
      main/exercise/exercise.class.php
  12. 2
      main/exercise/exercise.php
  13. 15
      main/exercise/exercise_show.php
  14. 7
      main/exercise/exercise_submit.php
  15. 2
      main/exercise/exercise_submit_modal.php
  16. 1
      main/exercise/export/qti2/qti2_classes.php
  17. 30
      main/exercise/fill_blanks.class.php
  18. 15
      main/exercise/global_multiple_answer.class.php
  19. 2
      main/exercise/hotspot.class.php
  20. 14
      main/exercise/matching.class.php
  21. 14
      main/exercise/multiple_answer.class.php
  22. 14
      main/exercise/multiple_answer_combination.class.php
  23. 21
      main/exercise/multiple_answer_true_false.class.php
  24. 5
      main/exercise/overview.php
  25. 18
      main/exercise/question.class.php
  26. 2
      main/exercise/question_admin.inc.php
  27. 3
      main/exercise/question_pool.php
  28. 1
      main/exercise/stats.php
  29. 14
      main/exercise/unique_answer.class.php
  30. 18
      main/exercise/unique_answer_no_option.class.php
  31. BIN
      main/img/icons/22/attempt-check.png
  32. BIN
      main/img/icons/22/attempt-nocheck.png
  33. 46
      main/inc/lib/exercise.lib.php
  34. 359
      main/inc/lib/exercise_show_functions.lib.php
  35. 3
      main/install/configuration.dist.php

@ -7327,3 +7327,47 @@ input.form-control[type="color"] {
.popover-content .popover-teacher .teachers-details{
text-align: left;
}
.feedback-green {
color: green;
}
.feedback-red {
color: red;
text-decoration: line-through;
}
.feedback-question {
margin-top: 5px;
margin-bottom: 5px;
display: block;
}
.feedback-separator {
font-size:120%;
}
.score-title {
color: #162a83;
font-weight: bold;
font-size: 16px;
}
.score-limits{
padding-top: 5px;
padding-bottom: 5px;
}
.score-limits .score-img{
display: inline-block;
padding-right: 5px;
}
.feedback-question img {
padding-right: 5px;
}
.question_row_answer img, .question_row img {
max-width: 80%;
height: auto !important;
}

@ -213,11 +213,16 @@ class Draggable extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>' . get_lang('ElementList').'</th>
<th>' . get_lang('Status').'</th>
</tr>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('YourChoice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
} else {
$header .= '<th>'.get_lang('ElementList').'</th>';
}
$header .= '<th>'.get_lang('Status').'</th>';
$header .= '</tr>';
return $header;
}

@ -144,3 +144,4 @@ if ($content_type == 'text/html') {
$fp = fopen($full_file_name, 'rb');
fpassthru($fp);
fclose($fp);

@ -264,11 +264,18 @@ class MatchingDraggable extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>' . get_lang('ElementList').'</th>
<th>' . get_lang('CorrespondsTo').'</th>
</tr>';
$header .= '<table class="matching '.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('ElementList').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('YourChoice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Status').'</th>';
} else {
$header .= '<th>'.get_lang('ElementList').'</th>';
$header .= '<th>'.get_lang('CorrespondsTo').'</th>';
}
$header .= '</tr>';
return $header;
}

@ -615,36 +615,34 @@ class TestCategory
/**
* @param int $questionId
* @param int $displayCategoryName
*/
public static function displayCategoryAndTitle($questionId)
public static function displayCategoryAndTitle($questionId, $displayCategoryName = 1)
{
echo self::returnCategoryAndTitle($questionId);
echo self::returnCategoryAndTitle($questionId, $displayCategoryName);
}
/**
* @param int $questionId
* @param int $in_display_category_name
* @return null|string
*/
public static function returnCategoryAndTitle($questionId)
public static function returnCategoryAndTitle($questionId, $in_display_category_name = 1)
{
$isStudent = !(api_is_allowed_to_edit(null, true) || api_is_session_admin());
$is_student = !(api_is_allowed_to_edit(null, true) || api_is_session_admin());
$objExercise = Session::read('objExercise');
if (empty($objExercise)) {
return '';
if (!empty($objExercise)) {
$in_display_category_name = $objExercise->display_category_name;
}
$showCategoryName = !!$objExercise->display_category_name; //double negation to get a boolean value
$categoryName = self::getCategoryNameForQuestion($questionId);
if (empty($categoryName) || (!$showCategoryName && $isStudent)) {
return '';
$content = null;
if (self::getCategoryNameForQuestion($questionId) != '' &&
($in_display_category_name == 1 || !$is_student)
) {
$content .= '<div class="page-header">';
$content .= '<h4>'.get_lang('Category').": ".self::getCategoryNameForQuestion($questionId).'</h4>';
$content .= "</div>";
}
return Display::page_header(
get_lang('Category').': '.$categoryName,
null,
'h4'
);
return $content;
}
/**
@ -1018,7 +1016,7 @@ class TestCategory
public function returnCategoryForm(Exercise $exercise)
{
$categories = $this->getListOfCategoriesForTest($exercise);
$saved_categories = $exercise->get_categories_in_exercise();
$saved_categories = $exercise->getCategoriesInExercise();
$return = null;
if (!empty($categories)) {
@ -1054,7 +1052,6 @@ class TestCategory
$cat_id = $category['iid'];
$return .= '<tr>';
$return .= '<td>';
//$return .= Display::div(isset($category['parent_path']) ? $category['parent_path'] : '');
$return .= Display::div($category['name']);
$return .= '</td>';
$return .= '<td>';
@ -1234,13 +1231,18 @@ class TestCategory
return $html;
}
// To allowed " in javascript dialog box without bad surprises
// replace " with two '
public function protectJSDialogQuote($in_txt)
/**
* To allowed " in javascript dialog box without bad surprises
* replace " with two '
* @param string $text
* @return mixed
*/
public function protectJSDialogQuote($text)
{
$res = $in_txt;
$res = $text;
$res = str_replace("'", "\'", $res);
$res = str_replace('"', "\'\'", $res); // super astuce pour afficher les " dans les boite de dialogue
// super astuce pour afficher les " dans les boite de dialogue
$res = str_replace('"', "\'\'", $res);
return $res;
}
}

@ -367,4 +367,28 @@ class UniqueAnswerImage extends UniqueAnswer
$this->updateWeighting($questionWeighting);
$this->save($exercise);
}
/**
* @param Exercise $exercise
* @param null $counter
* @param null $score
* @return string
*/
public function return_header($exercise, $counter = null, $score = null)
{
if ($exercise->showExpectedChoice()) {
$header = '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang('Choice').'</th>
<th>'.get_lang('ExpectedChoice').'</th>
<th>'.get_lang('Answer').'</th>';
$header .= '<th>'.get_lang('Status').'</th>';
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';
} else {
$header = parent::return_header($exercise, $counter, $score);
}
return $header;
}
}

@ -24,7 +24,6 @@ use ChamiloSession as Session;
* - $objExercise : exercise object
* - $objQuestion : question object
* - $objAnswer : answer object
* - $aType : array with answer types
* - $exerciseId : the exercise ID
* - $picturePath : the path of question pictures
* - $newQuestion : ask to create a new question
@ -135,17 +134,7 @@ $picturePath = $documentPath.'/images';
// audio path
$audioPath = $documentPath.'/audio';
// the 5 types of answers
$aType = [
get_lang('UniqueSelect'),
get_lang('MultipleSelect'),
get_lang('FillBlanks'),
get_lang('Matching'),
get_lang('FreeAnswer')
];
// tables used in the exercise tool
if (!empty($_GET['action']) && $_GET['action'] == 'exportqti2' && !empty($_GET['questionId'])) {
require_once 'export/qti2/qti2_export.php';
$export = export_question_qti($_GET['questionId'], true);
@ -264,7 +253,7 @@ if (!empty($clone_question) && !empty($objExercise->id)) {
$new_answer_obj->read();
$new_answer_obj->duplicate($new_question_obj);
//Reloading tne $objExercise obj
// Reloading tne $objExercise obj
$objExercise->read($objExercise->id);
header('Location: admin.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id);
@ -317,25 +306,6 @@ if ($modifyIn == 'thisExercise') {
$modifyIn = 'allExercises';
}
}
$htmlHeadXtra[] = '<script>
function multiple_answer_true_false_onchange(variable) {
var result = variable.checked;
var id = variable.id;
var weight_id = "weighting_" + id;
var array_result=new Array();
array_result[1]="1";
array_result[0]= "-0.50";
array_result[-1]= "0";
if (result) {
result = 1;
} else {
result = 0;
}
document.getElementById(weight_id).value = array_result[result];
}
</script>';
$htmlHeadXtra[] = api_get_js('jqueryui-touch-punch/jquery.ui.touch-punch.min.js');
$htmlHeadXtra[] = api_get_js('jquery.jsPlumb.all.js');
@ -391,11 +361,9 @@ if ($inATest) {
}
echo '</div>';
if ($objExercise->added_in_lp()) {
echo Display::return_message(get_lang('AddedToLPCannotBeAccessed'), 'warning');
}
echo '<div class="alert alert-info">';
echo sprintf(
get_lang('XQuestionsWithTotalScoreY'),
@ -404,8 +372,7 @@ if ($inATest) {
);
if ($objExercise->random > 0) {
echo '<br />'.
sprintf(get_lang('OnlyXQuestionsPickedRandomly'), $objExercise->random);
echo '<br />'.sprintf(get_lang('OnlyXQuestionsPickedRandomly'), $objExercise->random);
}
echo '</div>';
} elseif (isset($_GET['newQuestion'])) {

@ -647,10 +647,8 @@ class Answer
$hotspot_coordinates = isset($this->new_hotspot_coordinates[$i]) ? $this->new_hotspot_coordinates[$i] : '';
$hotspot_type = isset($this->new_hotspot_type[$i]) ? $this->new_hotspot_type[$i] : '';
$destination = isset($this->new_destination[$i]) ? $this->new_destination[$i] : '';
$autoId = $this->selectAutoId($i);
$iid = isset($this->iid[$i]) ? $this->iid[$i] : 0;
$questionType = $this->getQuestionType();
if (!isset($this->position[$i])) {
$quizAnswer = new CQuizAnswer();
@ -672,7 +670,6 @@ class Answer
$iid = $quizAnswer->getIid();
if ($iid) {
$quizAnswer
->setId($iid)
@ -681,7 +678,12 @@ class Answer
$em->merge($quizAnswer);
$em->flush();
if (in_array($questionType, [MATCHING, MATCHING_DRAGGABLE])) {
$questionType = $this->getQuestionType();
if (in_array(
$questionType,
[MATCHING, MATCHING_DRAGGABLE]
)) {
$answer = new Answer($this->questionId);
$answer->read();
$correctAnswerId = $answer->selectAnswerIdByPosition($correct);

@ -250,10 +250,15 @@ class CalculatedAnswer extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang("Answer").'</th>
</tr>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('YourChoice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '</tr>';
return $header;
}

@ -1,5 +1,6 @@
<?php
/* For licensing terms, see /license.txt */
require_once "../inc/global.inc.php";
echo "<pre>".

@ -462,6 +462,7 @@ class Exercise
*/
public function updateRandomByCat($random)
{
$this->randomByCat = EXERCISE_CATEGORY_RANDOM_DISABLED;
if (in_array(
$random,
[
@ -471,8 +472,6 @@ class Exercise
]
)) {
$this->randomByCat = $random;
} else {
$this->randomByCat = EXERCISE_CATEGORY_RANDOM_DISABLED;
}
}
@ -495,11 +494,11 @@ class Exercise
*/
public function isRandom()
{
$isRandom = false;
if ($this->random > 0 || $this->random == -1) {
return true;
} else {
return false;
$isRandom = true;
}
return $isRandom;
}
/**
@ -792,7 +791,6 @@ class Exercise
e.c_id = {$this->course_id} AND
e.exercice_id = '".$this->id."'
ORDER BY question_order";
$result = Database::query($sql);
// Fills the array with the question ID for this exercise
@ -1065,6 +1063,7 @@ class Exercise
// Adding category info in the category list with question list:
if (!empty($questions_by_category)) {
$newCategoryList = [];
$em = Database::getManager();
foreach ($questions_by_category as $categoryId => $questionList) {
$cat = new TestCategory();
$cat = $cat->getCategory($categoryId);
@ -1239,11 +1238,11 @@ class Exercise
*/
public function isInList($questionId)
{
$inList = false;
if (is_array($this->questionList)) {
return in_array($questionId, $this->questionList);
} else {
return false;
$inList = in_array($questionId, $this->questionList);
}
return $inList;
}
/**
@ -1483,9 +1482,6 @@ class Exercise
*/
public function setRandom($random)
{
/*if ($random == 'all') {
$random = $this->selectNbrQuestions();
}*/
$this->random = $random;
}
@ -1573,28 +1569,24 @@ class Exercise
$pass_percentage = intval($this->pass_percentage);
$session_id = $this->sessionId;
//If direct we do not show results
// If direct we do not show results
$results_disabled = intval($this->results_disabled);
if ($feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) {
$results_disabled = 0;
} else {
$results_disabled = intval($this->results_disabled);
}
$expired_time = intval($this->expired_time);
// Exercise already exists
if ($id) {
// we prepare date in the database using the api_get_utc_datetime() function
$start_time = null;
if (!empty($this->start_time)) {
$start_time = $this->start_time;
} else {
$start_time = null;
}
$end_time = null;
if (!empty($this->end_time)) {
$end_time = $this->end_time;
} else {
$end_time = null;
}
$params = [
@ -1662,22 +1654,19 @@ class Exercise
}
} else {
// Creates a new exercise
// In this case of new exercise, we don't do the api_get_utc_datetime()
// for date because, bellow, we call function api_set_default_visibility()
// In this function, api_set_default_visibility,
// the Quiz is saved too, with an $id and api_get_utc_datetime() is done.
// If we do it now, it will be done twice (cf. https://support.chamilo.org/issues/6586)
$start_time = null;
if (!empty($this->start_time)) {
$start_time = $this->start_time;
} else {
$start_time = null;
}
$end_time = null;
if (!empty($this->end_time)) {
$end_time = $this->end_time;
} else {
$end_time = null;
}
$params = [
@ -1956,7 +1945,8 @@ class Exercise
);
if (api_get_setting('enable_quiz_scenario') == 'true') {
//Can't convert a question from one feedback to another if there is more than 1 question already added
// Can't convert a question from one feedback to another
// if there is more than 1 question already added
if ($this->selectNbrQuestions() == 0) {
$radios_feedback[] = $form->createElement(
'radio',
@ -2133,7 +2123,7 @@ class Exercise
);
$form->addGroup($radios, null, get_lang('ExerciseType'));
} else {
//Show options freeze
// Show options freeze
$radios_results_disabled[] = $form->createElement(
'radio',
'results_disabled',
@ -2165,7 +2155,7 @@ class Exercise
);
$result_disable_group->freeze();
//we force the options to the DirectFeedback exercisetype
// we force the options to the DirectFeedback exercisetype
$form->addElement('hidden', 'exerciseFeedbackType', EXERCISE_FEEDBACK_TYPE_DIRECT);
$form->addElement('hidden', 'exerciseType', ONE_PER_PAGE);
@ -2471,7 +2461,6 @@ class Exercise
$defaults = [];
if (api_get_setting('search_enabled') === 'true') {
require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
$form->addElement('checkbox', 'index_document', '', get_lang('SearchFeatureDoIndexDocument'));
$form->addSelectLanguage('language', get_lang('SearchFeatureDocumentLanguage'));
$specific_fields = get_specific_field_list();
@ -2972,10 +2961,10 @@ class Exercise
/**
* Copies an exercise (duplicate all questions and answers)
*/
public function copy_exercise()
public function copyExercise()
{
$exerciseObject = $this;
$categories = $exerciseObject->get_categories_in_exercise();
$categories = $exerciseObject->getCategoriesInExercise();
// Get all questions no matter the order/category settings
$questionList = $exerciseObject->getQuestionOrderedList();
// Force the creation of a new exercise
@ -3398,7 +3387,6 @@ class Exercise
</script>";
}
/**
* This function was originally found in the exercise_show.php
* @param int $exeId
@ -4114,6 +4102,10 @@ class Exercise
}
$answer = '';
$realCorrectTags = $correctTags;
$calculatedStatus = Display::label(get_lang('Incorrect'), 'danger');
$expectedAnswer = '';
$calculatedChoice = '';
for ($i = 0; $i < count($realCorrectTags); $i++) {
if ($i == 0) {
$answer .= $realText[0];
@ -4127,11 +4119,13 @@ class Exercise
$totalScore += $answerWeighting[$i];
// adds the word in green at the end of the string
$answer .= $correctTags[$i];
$calculatedChoice = $correctTags[$i];
} elseif (!empty($userTags[$i])) {
// else if the word entered by the student IS NOT the same as
// the one defined by the professor
// adds the word in red at the end of the string, and strikes it
$answer .= '<font color="red"><s>'.$userTags[$i].'</s></font>';
$answer .= '<font color="red"><s>' . $userTags[$i] . '</s></font>';
$calculatedChoice = $userTags[$i];
} else {
// adds a tabulation if no word has been typed by the student
$answer .= ''; // remove &nbsp; that causes issue
@ -4140,8 +4134,9 @@ class Exercise
if ($this->results_disabled != EXERCISE_FEEDBACK_TYPE_EXAM) {
$answer .= ' / <font color="green"><b>'.$realCorrectTags[$i].'</b></font>';
$calculatedStatus = Display::label(get_lang('Correct'), 'success');
$expectedAnswer = $realCorrectTags[$i];
}
$answer .= ']';
if (isset($realText[$i + 1])) {
@ -4213,7 +4208,9 @@ class Exercise
}
break;
case DRAGGABLE:
//no break
case MATCHING_DRAGGABLE:
//no break
case MATCHING:
if ($from_database) {
$sql = "SELECT id, answer, id_auto
@ -4238,10 +4235,14 @@ class Exercise
correct <> 0
ORDER BY id_auto";
$res_answers = Database::query($sql);
$options = [];
while ($a_answers = Database::fetch_array($res_answers)) {
$options[] = $a_answers;
}
$questionScore = 0;
while ($a_answers = Database::fetch_array($res_answers)) {
$counterAnswer = 1;
foreach ($options as $a_answers) {
$i_answer_id = $a_answers['id']; //3
$s_answer_label = $a_answers['answer']; // your daddy - your mother
$i_answer_correct_answer = $a_answers['correct']; //1 - 2
@ -4265,19 +4266,30 @@ class Exercise
$i_answerWeighting = $a_answers['ponderation'];
$user_answer = '';
$status = Display::label(get_lang('Incorrect'), 'danger');
if (!empty($s_user_answer)) {
if ($answerType == DRAGGABLE) {
if ($s_user_answer == $i_answer_correct_answer) {
$questionScore += $i_answerWeighting;
$totalScore += $i_answerWeighting;
$user_answer = Display::label(get_lang('Correct'), 'success');
if ($this->showExpectedChoice()) {
$user_answer = $answerMatching[$i_answer_id_auto];
}
$status = Display::label(get_lang('Correct'), 'success');
} else {
$user_answer = Display::label(get_lang('Incorrect'), 'danger');
if ($this->showExpectedChoice()) {
$data = $options[$real_list[$s_user_answer] - 1];
$user_answer = $data['answer'];
}
}
} else {
if ($s_user_answer == $i_answer_correct_answer) {
$questionScore += $i_answerWeighting;
$totalScore += $i_answerWeighting;
$status = Display::label(get_lang('Correct'), 'success');
// Try with id
if (isset($real_list[$i_answer_id])) {
@ -4297,10 +4309,18 @@ class Exercise
$real_list[$s_user_answer],
['style' => 'color: #FF0000; text-decoration: line-through;']
);
if ($this->showExpectedChoice()) {
$user_answer = Display::span(
$real_list[$s_user_answer]
);
}
}
}
} elseif ($answerType == DRAGGABLE) {
$user_answer = Display::label(get_lang('Incorrect'), 'danger');
if ($this->showExpectedChoice()) {
$user_answer = '';
}
} else {
$user_answer = Display::span(
get_lang('Incorrect').' &nbsp;',
@ -4312,23 +4332,73 @@ class Exercise
if ($showTotalScoreAndUserChoicesInLastAttempt === false) {
$user_answer = '';
}
echo '<tr>';
echo '<td>'.$s_answer_label.'</td>';
echo '<td>'.$user_answer;
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt === true
) {
echo Display::span(
$real_list[$i_answer_correct_answer],
['style' => 'color: #008000; font-weight: bold;']
);
}
switch ($answerType) {
case MATCHING:
case MATCHING_DRAGGABLE:
echo '<tr>';
if ($this->showExpectedChoice()) {
echo '<td>'.$s_answer_label.'</td>';
echo '<td>'.$user_answer.'</td>';
echo '<td>';
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt == true
) {
echo Display::span(
$real_list[$i_answer_correct_answer]
);
}
}
echo '</td>';
echo '<td>'.$status.'</td>';
} else {
echo '<td>'.$s_answer_label.'</td>';
echo '<td>'.$user_answer.'</td>';
echo '<td>';
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt === true
) {
echo Display::span(
$real_list[$i_answer_correct_answer],
['style' => 'color: #008000; font-weight: bold;']
);
}
}
echo '</td>';
}
echo '</tr>';
break;
case DRAGGABLE:
if ($showTotalScoreAndUserChoicesInLastAttempt == false) {
$s_answer_label = '';
}
echo '<tr>';
if ($this->showExpectedChoice()) {
echo '<td>'.$user_answer.'</td>';
echo '<td>'.$s_answer_label.'</td>';
echo '<td>'.$status.'</td>';
} else {
echo '<td>'.$s_answer_label.'</td>';
echo '<td>'.$user_answer.'</td>';
echo '<td>';
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer]) &&
$showTotalScoreAndUserChoicesInLastAttempt === true
) {
echo Display::span(
$real_list[$i_answer_correct_answer],
['style' => 'color: #008000; font-weight: bold;']
);
}
}
echo '</td>';
}
echo '</tr>';
break;
}
echo '</td>';
echo '</tr>';
}
$counterAnswer++;
}
break(2); // break the switch and the "for" condition
} else {
@ -4565,6 +4635,7 @@ class Exercise
]
)) {
ExerciseShowFunctions::display_unique_or_multiple_answer(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4580,6 +4651,7 @@ class Exercise
);
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
ExerciseShowFunctions::display_multiple_answer_true_false(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4594,6 +4666,7 @@ class Exercise
);
} elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
ExerciseShowFunctions::display_multiple_answer_combination_true_false(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4618,12 +4691,16 @@ class Exercise
);
} elseif ($answerType == CALCULATED_ANSWER) {
ExerciseShowFunctions::display_calculated_answer(
$this,
$feedback_type,
$answer,
0,
0,
$results_disabled,
$showTotalScoreAndUserChoicesInLastAttempt
$showTotalScoreAndUserChoicesInLastAttempt,
$expectedAnswer,
$calculatedChoice,
$calculatedStatus
);
} elseif ($answerType == FREE_ANSWER) {
ExerciseShowFunctions::display_free_answer(
@ -4657,6 +4734,9 @@ class Exercise
}
}
// force to show whether the choice is correct or not
$showTotalScoreAndUserChoicesInLastAttempt = true;
ExerciseShowFunctions::display_hotspot_answer(
$feedback_type,
++$correctAnswerId,
@ -4781,7 +4861,7 @@ class Exercise
$result_comment = get_lang('Unacceptable');
$comment = $answerDestination = $objAnswerTmp->selectComment(1);
$answerDestination = $objAnswerTmp->selectDestination(1);
//checking the destination parameters parsing the "@@"
// checking the destination parameters parsing the "@@"
$destination_items = explode('@@', $answerDestination);
}
} elseif ($answerId > 1) {
@ -4796,10 +4876,6 @@ 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, '|');
@ -4863,14 +4939,21 @@ class Exercise
switch ($answerType) {
case UNIQUE_ANSWER:
//no break
case UNIQUE_ANSWER_IMAGE:
//no break
case UNIQUE_ANSWER_NO_OPTION:
//no break
case MULTIPLE_ANSWER:
//no break
case GLOBAL_MULTIPLE_ANSWER:
//no break
case MULTIPLE_ANSWER_COMBINATION:
//no break
case READING_COMPREHENSION:
if ($answerId == 1) {
ExerciseShowFunctions::display_unique_or_multiple_answer(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4886,6 +4969,7 @@ class Exercise
);
} else {
ExerciseShowFunctions::display_unique_or_multiple_answer(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4904,6 +4988,7 @@ class Exercise
case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
if ($answerId == 1) {
ExerciseShowFunctions::display_multiple_answer_combination_true_false(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4918,6 +5003,7 @@ class Exercise
);
} else {
ExerciseShowFunctions::display_multiple_answer_combination_true_false(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4935,6 +5021,7 @@ class Exercise
case MULTIPLE_ANSWER_TRUE_FALSE:
if ($answerId == 1) {
ExerciseShowFunctions::display_multiple_answer_true_false(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4949,6 +5036,7 @@ class Exercise
);
} else {
ExerciseShowFunctions::display_multiple_answer_true_false(
$this,
$feedback_type,
$answerType,
$studentChoice,
@ -4976,6 +5064,7 @@ class Exercise
break;
case CALCULATED_ANSWER:
ExerciseShowFunctions::display_calculated_answer(
$this,
$feedback_type,
$answer,
$exeId,
@ -5186,7 +5275,9 @@ class Exercise
);
break;
case DRAGGABLE:
//no break
case MATCHING_DRAGGABLE:
//no break
case MATCHING:
echo '<tr>';
echo Display::tag('td', $answerMatching[$answerId]);
@ -6947,7 +7038,7 @@ class Exercise
* Get categories added in the exercise--category matrix
* @return array
*/
public function get_categories_in_exercise()
public function getCategoriesInExercise()
{
$table = Database::get_course_table(TABLE_QUIZ_REL_CATEGORY);
if (!empty($this->id)) {
@ -7695,7 +7786,6 @@ class Exercise
}
$sessionId = intval($sessionId);
$ids = is_array($quizId) ? $quizId : [$quizId];
$ids = array_map('intval', $ids);
$ids = implode(',', $ids);
@ -7867,7 +7957,9 @@ class Exercise
$isCorrect = FillBlanks::isCorrect($answer['answer']);
break;
case MATCHING:
//no break
case DRAGGABLE:
//no break
case MATCHING_DRAGGABLE:
$isCorrect = Matching::isCorrect(
$answer['position'],
@ -7940,4 +8032,62 @@ class Exercise
{
return $this->notifications;
}
/**
* @return bool
*/
public function showExpectedChoice()
{
return api_get_configuration_value('show_exercise_expected_choice');
}
/**
* @param string $class
* @param string $scoreLabel
* @param string $result
* @param array
*
* @return string
*/
public function getQuestionRibbon($class, $scoreLabel, $result, $array)
{
if ($this->showExpectedChoice()) {
$html = null;
$hideLabel = api_get_configuration_value('exercise_hide_label');
$label = '<div class="rib rib-'.$class.'">
<h3>'.$scoreLabel.'</h3>
</div>
<h4>'.get_lang('Score').': '.$result.'</h4>';
if ($hideLabel === true) {
$answerUsed = (int) $array['used'];
$answerMissing = (int) $array['missing'] - $answerUsed;
for ($i = 1; $i <= $answerUsed; $i++) {
$html.= '<span class="score-img">'.
Display::return_icon('attempt-check.png', null, null, ICON_SIZE_SMALL).
'</span>';
}
for ($i = 1; $i <= $answerMissing; $i++) {
$html.= '<span class="score-img">'.
Display::return_icon('attempt-nocheck.png', null, null, ICON_SIZE_SMALL).
'</span>';
}
$label = '<div class="score-title">'.get_lang('CorrectAnswers').': '.$result.'</div>';
$label .= '<div class="score-limits">';
$label .= $html;
$label .= '</div>';
}
return '<div class="ribbon">
'.$label.'
</div>'
;
} else {
return '<div class="ribbon">
<div class="rib rib-'.$class.'">
<h3>'.$scoreLabel.'</h3>
</div>
<h4>'.get_lang('Score').': '.$result.'</h4>
</div>'
;
}
}
}

@ -296,7 +296,7 @@ if ($is_allowedToEdit) {
}
break;
case 'copy_exercise': //copy an exercise
$objExerciseTmp->copy_exercise();
$objExerciseTmp->copyExercise();
echo Display::return_message(
get_lang('ExerciseCopied'),
'confirmation'

@ -396,20 +396,35 @@ foreach ($questionList as $questionId) {
$relPath = api_get_path(WEB_CODE_PATH);
switch ($answerType) {
case MULTIPLE_ANSWER_COMBINATION:
//no break
case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
//no break
case UNIQUE_ANSWER:
//no break;
case UNIQUE_ANSWER_NO_OPTION:
//no break
case UNIQUE_ANSWER_IMAGE:
//no break
case MULTIPLE_ANSWER:
//no break
case MULTIPLE_ANSWER_TRUE_FALSE:
//no break
case FILL_IN_BLANKS:
//no break
case CALCULATED_ANSWER:
//no break
case GLOBAL_MULTIPLE_ANSWER:
//no break
case FREE_ANSWER:
//no break
case ORAL_EXPRESSION:
//no break
case MATCHING:
//no break
case DRAGGABLE:
//no break
case READING_COMPREHENSION:
//no break
case MATCHING_DRAGGABLE:
$question_result = $objExercise->manage_answer(
$id,

@ -1369,10 +1369,13 @@ if (!empty($error)) {
false,
$origin,
$i,
true,
$objExercise->getHideQuestionTitle() ? false : true,
false,
$user_choice,
false
false,
null,
false,
true
);
// Button save and continue

@ -223,9 +223,7 @@ if (!empty($choice_value)) {
break;
}
if ($answerType == UNIQUE_ANSWER || $answerType == MULTIPLE_ANSWER) {
//display_unique_or_multiple_answer($answerType, $studentChoice, $answer, $answerComment, $answerCorrect);
if ($studentChoice) {
$destination = $answerDestination;
$comment = $answerComment;

@ -33,6 +33,7 @@ class Ims2Question extends Question
return $answer;
case MATCHING:
//no break
case MATCHING_DRAGGABLE:
$answer = new ImsAnswerMatching($this->id);

@ -537,8 +537,6 @@ class FillBlanks extends Question
$resultOptions[sha1($item)] = $item;
}
//var_dump($resultOptions, $correctItem);
foreach ($resultOptions as $key => $value) {
if ($correctItem == $value) {
$selected = $key;
@ -556,6 +554,7 @@ class FillBlanks extends Question
);
break;
case self::FILL_THE_BLANK_SEVERAL_ANSWER:
//no break
case self::FILL_THE_BLANK_STANDARD:
default:
$attributes['id'] = 'choice_id_'.$currentQuestion.'_'.$inBlankNumber;
@ -1232,26 +1231,28 @@ class FillBlanks extends Question
$showTotalScoreAndUserChoices = false
) {
$hideExpectedAnswer = false;
if ($feedbackType == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
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;
} else {
$hideExpectedAnswer = true;
}
}
$style = "color: green";
$style = 'feedback-green';
$iconAnswer = Display::return_icon('attempt-check.png', get_lang('Correct'), null, ICON_SIZE_SMALL);
if (!$right) {
$style = "color: red; text-decoration: line-through;";
$style = 'feedback-red';
$iconAnswer = Display::return_icon('attempt-nocheck.png', get_lang('Incorrect'), null, ICON_SIZE_SMALL);
}
$correctAnswerHtml = '';
$type = self::getFillTheBlankAnswerType($correct);
switch ($type) {
case self::FILL_THE_BLANK_MENU:
$correctAnswerHtml = '';
$listPossibleAnswers = self::getFillTheBlankMenuAnswers($correct, false);
$correctAnswerHtml .= "<span style='color: green'>".$listPossibleAnswers[0]."</span>";
$correctAnswerHtml .= " <span style='font-weight:normal'>(";
@ -1269,20 +1270,21 @@ class FillBlanks extends Question
if (count($listCorrects) > 0) {
$firstCorrect = $listCorrects[0];
}
$correctAnswerHtml = "<span style='color: green'>".$firstCorrect."</span>";
$correctAnswerHtml = "<span class='feedback-red'>".$firstCorrect."</span>";
break;
case self::FILL_THE_BLANK_STANDARD:
// no break
default:
$correctAnswerHtml = "<span style='color: green'>".$correct."</span>";
$correctAnswerHtml = "<span class='feedback-green'>".$correct."</span>";
}
if ($hideExpectedAnswer) {
$correctAnswerHtml = "<span title='".get_lang("ExerciseWithFeedbackWithoutCorrectionComment")."'> - </span>";
$correctAnswerHtml = "<span class='feedback-green' title='".get_lang('ExerciseWithFeedbackWithoutCorrectionComment')."'> &#8212; </span>";
}
$result = "<span style='border:1px solid black; border-radius:5px; padding:2px; font-weight:bold;'>";
$result .= "<span style='$style'>".$answer."</span>";
$result .= "&nbsp;<span style='font-size:120%;'>/</span>&nbsp;";
$result = "<span class='feedback-question'>";
$result .= $iconAnswer."<span class='$style'>".$answer."</span>";
$result .= "<span class='feedback-separator'> / </span>";
$result .= $correctAnswerHtml;
$result .= "</span>";

@ -265,12 +265,15 @@ class GlobalMultipleAnswer extends Question
$score = null
) {
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>' . get_lang("Choice").'</th>
<th>' . get_lang("ExpectedChoice").'</th>
<th>' . get_lang("Answer").'</th>';
$header .= '<th>'.get_lang("Comment").'</th>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';
return $header;

@ -67,7 +67,7 @@ class HotSpot extends Question
} else {
// setting the save button here and not in the question class.php
// Editing a question
$form->addButtonUpdate(get_lang('ModifyExercise'), 'submitQuestion');
$form->addButtonUpdate(get_lang('ModifyQuestion'), 'submitQuestion');
}
}

@ -283,10 +283,16 @@ class Matching extends Question
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">';
$header .= '<tr>
<th>'.get_lang('ElementList').'</th>
<th>'.get_lang('CorrespondsTo').'</th>
</tr>';
$header .= '<tr>';
$header .= '<th>'.get_lang('ElementList').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('YourChoice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Status').'</th>';
} else {
$header .= '<th>'.get_lang('CorrespondsTo').'</th>';
}
$header .= '</tr>';
return $header;
}

@ -228,12 +228,14 @@ class MultipleAnswer extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang("Choice").'</th>
<th>'. get_lang("ExpectedChoice").'</th>
<th>'. get_lang("Answer").'</th>';
$header .= '<th>'.get_lang("Comment").'</th>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';
return $header;
}

@ -227,12 +227,14 @@ class MultipleAnswerCombination extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang("Choice").'</th>
<th>'. get_lang("ExpectedChoice").'</th>
<th>'. get_lang("Answer").'</i></th>';
$header .= '<th>'.get_lang("Comment").'</th>';
$header .= '<table class="'.$this->question_table_class.'"><tr>
<th>'.get_lang('Choice').'</th>
<th>'.get_lang('ExpectedChoice').'</th>
<th>'.get_lang('Answer').'</i></th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';
return $header;

@ -267,11 +267,10 @@ class MultipleAnswerTrueFalse extends Question
/* Getting quiz_question_options (true, false, doubt) because
it's possible that there are more options in the future */
$new_options = Question::readQuestionOption($this->id, $course_id);
$sorted_by_position = [];
$sortedByPosition = [];
foreach ($new_options as $item) {
$sorted_by_position[$item['position']] = $item;
$sortedByPosition[$item['position']] = $item;
}
/* Saving quiz_question.extra values that has the correct scores of
@ -291,7 +290,7 @@ class MultipleAnswerTrueFalse extends Question
if (empty($options)) {
//If this is the first time that the question is created when
// change the default values from the form 1 and 2 by the correct "option id" registered
$goodAnswer = $sorted_by_position[$goodAnswer]['id'];
$goodAnswer = isset($sortedByPosition[$goodAnswer]) ? $sortedByPosition[$goodAnswer]['id'] : '';
}
$questionWeighting += $extra_values[0]; //By default 0 has the correct answers
$objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i);
@ -310,13 +309,15 @@ class MultipleAnswerTrueFalse extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang("Choice").'</th>
<th>'. get_lang("ExpectedChoice").'</th>
<th>'. get_lang("Answer").'</th>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>
<th>'.get_lang('ExpectedChoice').'</th>
<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
if ($exercise->feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
$header .= '<th>'.get_lang("Comment").'</th>';
$header .= '<th>'.get_lang('Comment').'</th>';
} else {
$header .= '<th>&nbsp;</th>';
}

@ -110,11 +110,6 @@ $exercise_stat_info = $objExercise->get_stat_track_exercise_info(
0
);
/*$attempt_list = null;
if (isset($exercise_stat_info['exe_id'])) {
$attempt_list = Event::getAllExerciseEventByExeId($exercise_stat_info['exe_id']);
}*/
//1. Check if this is a new attempt or a previous
$label = get_lang('StartTest');
if ($time_control && !empty($clock_expired_time) || isset($exercise_stat_info['exe_id'])) {

@ -1682,7 +1682,6 @@ abstract class Question
$form->addGroup($buttonGroup);
break;
}
//Medias
//$course_medias = self::prepare_course_media_select(api_get_course_int_id());
//$form->addElement('select', 'parent_id', get_lang('AttachToMedia'), $course_medias);
@ -1954,9 +1953,9 @@ abstract class Question
*/
public function return_header($exercise, $counter = null, $score = [])
{
$counter_label = '';
$counterLabel = '';
if (!empty($counter)) {
$counter_label = intval($counter);
$counterLabel = intval($counter);
}
$score_label = get_lang('Wrong');
$class = 'error';
@ -1992,13 +1991,16 @@ abstract class Question
if ($exercise->display_category_name) {
$header = TestCategory::returnCategoryAndTitle($this->id);
}
$show_media = null;
$show_media = '';
if ($show_media) {
$header .= $this->show_media_content();
}
$header .= Display::page_subheader2($counter_label.". ".$this->question);
$header .= ExerciseLib::getQuestionRibbon($class, $score_label, $score['result']);
$scoreCurrent = [
'used' => $score['score'],
'missing' => $score['weight']
];
$header .= Display::page_subheader2($counterLabel.'. '.$this->question);
$header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent);
if ($this->type != READING_COMPREHENSION) {
// Do not show the description (the text to read) if the question is of type READING_COMPREHENSION
$header .= Display::div(
@ -2303,6 +2305,6 @@ abstract class Question
*/
public function returnFormatFeedback()
{
return Display::return_message($this->feedback, 'normal', false);
return '<br />'.Display::return_message($this->feedback, 'normal', false);
}
}

@ -52,9 +52,7 @@ if (is_object($objQuestion)) {
// Question
$objQuestion->processCreation($form, $objExercise);
$objQuestion->processAnswersCreation($form, $objExercise);
// TODO: maybe here is the better place to index this tool, including answers text
// redirect
if ($objQuestion->type != HOT_SPOT &&
$objQuestion->type != HOT_SPOT_DELINEATION

@ -48,7 +48,7 @@ if (empty($objExercise) && !empty($fromExercise)) {
}
$nameTools = get_lang('QuestionPool');
$interbreadcrumb[] = ["url" => "exercise.php", "name" => get_lang('Exercises')];
$interbreadcrumb[] = ["url" => "exercise.php?".api_get_cidreq(), "name" => get_lang('Exercises')];
if (!empty($objExercise)) {
$interbreadcrumb[] = [
@ -299,7 +299,6 @@ if (empty($selected_course) || $selected_course == '-1') {
} else {
$course_info = api_get_course_info_by_id($selected_course);
}
// If course has changed, reset the menu default
if ($course_id_changed) {
reset_menu_exo_lvl_type();

@ -185,6 +185,7 @@ if (!empty($question_list)) {
}
break;
case MATCHING:
//no break
case MATCHING_DRAGGABLE:
if ($is_correct == 0) {
if ($answer_id == 1) {

@ -417,12 +417,14 @@ class UniqueAnswer extends Question
$score = null
) {
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang("Choice").'</th>
<th>'.get_lang("ExpectedChoice").'</th>
<th>'.get_lang("Answer").'</th>';
$header .= '<th>'.get_lang("Comment").'</th>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';
return $header;

@ -23,8 +23,8 @@ class UniqueAnswerNoOption extends Question
public function __construct()
{
parent::__construct();
$this -> type = UNIQUE_ANSWER_NO_OPTION;
$this -> isContent = $this-> getIsContent();
$this->type = UNIQUE_ANSWER_NO_OPTION;
$this->isContent = $this->getIsContent();
}
/**
@ -409,12 +409,14 @@ class UniqueAnswerNoOption extends Question
public function return_header($exercise, $counter = null, $score = null)
{
$header = parent::return_header($exercise, $counter, $score);
$header .= '<table class="'.$this->question_table_class.'">
<tr>
<th>'.get_lang("Choice").'</th>
<th>'.get_lang("ExpectedChoice").'</th>
<th>'.get_lang("Answer").'</th>';
$header .= '<th>'.get_lang("Comment").'</th>';
$header .= '<table class="'.$this->question_table_class.'"><tr>';
$header .= '<th>'.get_lang('Choice').'</th>';
$header .= '<th>'.get_lang('ExpectedChoice').'</th>';
$header .= '<th>'.get_lang('Answer').'</th>';
if ($exercise->showExpectedChoice()) {
$header .= '<th>'.get_lang('Status').'</th>';
}
$header .= '<th>'.get_lang('Comment').'</th>';
$header .= '</tr>';
return $header;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

@ -39,7 +39,8 @@ class ExerciseLib
$freeze = false,
$user_choice = [],
$show_comment = false,
$show_answers = false
$show_answers = false,
$show_icon = false
) {
$course_id = empty($exercise->course_id) ? api_get_course_int_id() : $exercise->course_id;
$course = api_get_course_info_by_id($course_id);
@ -309,8 +310,11 @@ class ExerciseLib
switch ($answerType) {
case UNIQUE_ANSWER:
//no break
case UNIQUE_ANSWER_NO_OPTION:
//no break
case UNIQUE_ANSWER_IMAGE:
//no break
case READING_COMPREHENSION:
$input_id = 'choice-'.$questionId.'-'.$answerId;
if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
@ -390,7 +394,9 @@ class ExerciseLib
}
break;
case MULTIPLE_ANSWER:
//no break
case MULTIPLE_ANSWER_TRUE_FALSE:
//no break
case GLOBAL_MULTIPLE_ANSWER:
$input_id = 'choice-'.$questionId.'-'.$answerId;
$answer = Security::remove_XSS($answer, STUDENT);
@ -987,7 +993,6 @@ HTML;
$draggableSelectOptions[$selectItem['id']] = $selectItem['letter'];
}
foreach ($draggableSelectOptions as $value => $text) {
if ($value == $selectedValue) {
break;
@ -3643,7 +3648,9 @@ EOT;
$select_condition = " e.exe_id, answer ";
break;
case MATCHING:
//no break
case MATCHING_DRAGGABLE:
//no break
default:
$answer_condition = " answer = $answer_id AND ";
$select_condition = " DISTINCT exe_user_id ";
@ -3700,7 +3707,9 @@ EOT;
return $good_answers;
break;
case MATCHING:
//no break
case MATCHING_DRAGGABLE:
//no break
default:
$return = Database::num_rows($result);
}
@ -4225,11 +4234,18 @@ EOT;
if ($show_results) {
$question_content .= '</div>';
}
if (!$show_only_score) {
if ($objExercise->showExpectedChoice()) {
$exercise_content .= Display::div(
Display::panel($question_content),
['class' => 'question-panel']
);
} else {
if (!$show_only_score) {
$exercise_content .= Display::div(
Display::panel($question_content),
['class' => 'question-panel']
);
}
}
} // end foreach() block that loops over all questions
}
@ -4271,6 +4287,12 @@ EOT;
);
echo $total_score_text;
// Ofaj change BT#11784
if (!empty($objExercise->description)) {
echo Display::div($objExercise->description, array('class'=>'exercise_description'));
}
echo $exercise_content;
if (!$show_only_score) {
@ -4322,24 +4344,6 @@ EOT;
}
}
/**
* @param string $class
* @param string $scoreLabel
* @param string $result
*
* @return string
*/
public static function getQuestionRibbon($class, $scoreLabel, $result)
{
return '<div class="ribbon">
<div class="rib rib-'.$class.'">
<h3>'.$scoreLabel.'</h3>
</div>
<h4>'.get_lang('Score').': '.$result.'</h4>
</div>'
;
}
/**
* @param Exercise $objExercise
* @param float $score

@ -44,71 +44,85 @@ class ExerciseShowFunctions
$resultsDisabled,
$showTotalScoreAndUserChoices
);
if (strpos($originalStudentAnswer, 'font color') !== false) {
// ofaj
/*if (strpos($originalStudentAnswer, 'font color') !== false) {
$answerHTML = $originalStudentAnswer;
}
}*/
if (empty($id)) {
echo '<tr><td>';
echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
echo '</td></tr>';
} else {
?>
<tr>
<td>
<?php echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY); ?>
</td>
<?php
if (!api_is_allowed_to_edit(null, true) && $feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td>
<?php
$comm = Event::get_comments($id, $questionId); ?>
</td>
<?php
} ?>
</tr>
<?php
echo '<tr><td>';
echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);
echo '</td>';
if (!api_is_allowed_to_edit(null, true) && $feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td>';
$comm = Event::get_comments($id, $questionId);
echo '</td>';
}
echo '</tr>';
}
}
/**
* Shows the answer to a calculated question, as HTML
* @param Exercise $exercise
* @param string Answer text
* @param int Exercise ID
* @param int Question ID
* @return void
*/
public static function display_calculated_answer(
$exercise,
$feedback_type,
$answer,
$id,
$questionId,
$results_disabled,
$showTotalScoreAndUserChoices
$showTotalScoreAndUserChoices,
$expectedChoice = '',
$choice = '',
$status = ''
) {
if (empty($id)) {
echo '<tr><td>'.Security::remove_XSS($answer).'</td></tr>';
if ($exercise->showExpectedChoice()) {
if (empty($id)) {
echo '<tr><td>'. Security::remove_XSS($answer).'</td>';
echo '<td>'. Security::remove_XSS($choice).'</td>';
echo '<td>'. Security::remove_XSS($expectedChoice).'</td>';
echo '<td>'. Security::remove_XSS($status).'</td>';
echo '</tr>';
} else {
echo '<tr><td>';
echo Security::remove_XSS($answer);
echo '</td><td>';
echo Security::remove_XSS($choice);
echo '</td><td>';
echo Security::remove_XSS($expectedChoice);
echo '</td><td>';
echo Security::remove_XSS($status);
echo '</td>';
if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td>';
$comm = Event::get_comments($id, $questionId);
echo '</td>';
}
echo '</tr>';
}
} else {
?>
<tr>
<td>
<?php
echo Security::remove_XSS($answer); ?>
</td>
if (empty($id)) {
echo '<tr><td>'.Security::remove_XSS($answer).'</td></tr>';
} else {
echo '<tr><td>';
echo Security::remove_XSS($answer);
if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td>';
$comm = Event::get_comments($id, $questionId);
echo '</td>';
<?php
if (!api_is_allowed_to_edit(null, true) && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td>
<?php
$comm = Event::get_comments($id, $questionId); ?>
</td>
<?php
} ?>
</tr>
<?php
}
echo '</tr>';
}
}
}
@ -226,10 +240,9 @@ class ExerciseShowFunctions
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
} else {
$hide_expected_answer = true;
}
}
@ -248,42 +261,38 @@ class ExerciseShowFunctions
"#ED2024",
"#3B3B3B",
"#F7BDE2"
]; ?>
<table class="data_table">
<tr>
<td class="text-center" width="5%">
<span class="fa fa-square fa-fw fa-2x" aria-hidden="true" style="color: <?php echo $hotspot_colors[$orderColor]; ?>"></span>
</td>
<td class="text-left" width="25%">
<?php echo "$answerId - $answer"; ?>
</td>
<td class="text-left" width="10%">
<?php
if (!$hide_expected_answer) {
$my_choice = $studentChoice ? get_lang('Correct') : get_lang('Fault');
echo $my_choice;
} ?>
</td>
<?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td class="text-left" width="60%">
<?php
if ($studentChoice) {
echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
} ?>
</td>
<?php
} else {
?>
<td class="text-left" width="60%">&nbsp;</td>
<?php
} ?>
</tr>
<?php
];
echo '<table class="data_table"><tr>';
echo '<td class="text-center" width="5%">';
echo '<span class="fa fa-square fa-fw fa-2x" aria-hidden="true" style="color:'.$hotspot_colors[$orderColor].'"></span>';
echo '</td>';
echo '<td class="text-left" width="25%">';
echo "$answerId - $answer";
echo '</td>';
echo '<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');
}
echo $status;
}
echo '</td>';
if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td class="text-left" width="60%">';
if ($studentChoice) {
echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
}
echo '</td>';
} else {
echo '<td class="text-left" width="60%">&nbsp;</td>';
}
echo '</tr>';
}
/**
* Display the answers to a multiple choice question
* @param Exercise $exercise
* @param int $feedback_type Feedback type
* @param int $answerType Answer type
* @param int $studentChoice Student choice
@ -299,6 +308,7 @@ class ExerciseShowFunctions
* @return void
*/
public static function display_unique_or_multiple_answer(
$exercise,
$feedback_type,
$answerType,
$studentChoice,
@ -330,10 +340,9 @@ class ExerciseShowFunctions
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
} else {
$hide_expected_answer = true;
}
}
@ -342,58 +351,59 @@ class ExerciseShowFunctions
$icon .= '.png';
$iconAnswer = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
$iconAnswer .= $answerCorrect ? '_on' : '_off';
$iconAnswer .= '.png'; ?>
<tr>
<td width="5%">
<?php echo Display::return_icon($icon, null, null, ICON_SIZE_TINY); ?>
</td>
<td width="5%">
<?php if (!$hide_expected_answer) {
$iconAnswer .= '.png';
echo '<tr>';
echo '<td width="5%">';
echo Display::return_icon($icon, null, null, ICON_SIZE_TINY);
echo '</td><td width="5%">';
if (!$hide_expected_answer) {
echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY);
} else {
echo "-";
} ?>
</td>
<td width="40%">
<?php
echo $answer; ?>
</td>
}
echo '</td><td width="40%">';
echo $answer;
echo '</td>';
if ($exercise->showExpectedChoice()) {
$status = Display::label(get_lang('Incorrect'), 'danger');
if ($studentChoice) {
if ($answerCorrect) {
$status = Display::label(get_lang('Correct'), 'success');
}
}
echo '<td width="20%">';
echo $status;
echo '</td>';
}
<?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td width="20%">
<?php
if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td width="20%">';
if ($studentChoice) {
$color = 'black';
if ($answerCorrect) {
$color = 'green';
//echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
} else {
$color = 'black';
//echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
}
if ($hide_expected_answer) {
$color = '';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
} ?>
</td>
<?php
echo '<span style="font-weight: bold; color: '.$color.';">'.strip_tags($answerComment).'</span>';
}
echo '</td>';
if ($ans == 1) {
$comm = Event::get_comments($id, $questionId);
} ?>
<?php
} else {
?>
<td>&nbsp;</td>
<?php
} ?>
</tr>
<?php
}
} else {
echo '<td>&nbsp;</td>';
}
echo '</tr>';
}
/**
* Display the answers to a multiple choice question
*
* @param Exercise $exercise
* @param integer Answer type
* @param integer Student choice
* @param string Textual answer
@ -405,6 +415,7 @@ class ExerciseShowFunctions
* @return void
*/
public static function display_multiple_answer_true_false(
$exercise,
$feedback_type,
$answerType,
$studentChoice,
@ -418,35 +429,27 @@ 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;
} else {
$hide_expected_answer = true;
}
} ?>
<tr>
<td width="5%">
<?php
$course_id = api_get_course_int_id();
}
echo '<tr><td width="5%">';
$course_id = api_get_course_int_id();
$new_options = Question::readQuestionOption($questionId, $course_id);
//Your choice
// Your choice
if (isset($new_options[$studentChoice])) {
echo get_lang($new_options[$studentChoice]['name']);
} else {
echo '-';
} ?>
</td>
<td width="5%">
<?php
//Expected choice
}
echo '</td><td width="5%">';
// Expected choice
if (!$hide_expected_answer) {
if (isset($new_options[$answerCorrect])) {
echo get_lang($new_options[$answerCorrect]['name']);
@ -455,16 +458,23 @@ class ExerciseShowFunctions
}
} else {
echo '-';
} ?>
</td>
<td width="40%">
<?php echo $answer; ?>
</td>
<?php if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td width="20%">
<?php
}
echo '</td><td width="40%">';
echo $answer;
echo '</td>';
if ($exercise->showExpectedChoice()) {
$status = Display::label(get_lang('Incorrect'), 'danger');
if (isset($new_options[$studentChoice])) {
if ($studentChoice == $answerCorrect) {
$status = Display::label(get_lang('Correct'), 'success');
}
}
echo '<td width="20%">';
echo $status;
echo '</td>';
}
if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<td width="20%">';
$color = "black";
if (isset($new_options[$studentChoice])) {
if ($studentChoice == $answerCorrect) {
@ -474,27 +484,22 @@ class ExerciseShowFunctions
if ($hide_expected_answer) {
$color = '';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
} ?>
</td>
<?php
}
echo '</td>';
if ($ans == 1) {
$comm = Event::get_comments($id, $questionId);
} ?>
<?php
}
} else {
?>
<td>&nbsp;</td>
<?php
} ?>
</tr>
<?php
echo '<td>&nbsp;</td>';
}
echo '</tr>';
}
/**
* Display the answers to a multiple choice question
*
* @param Exercise $exercise
* @param integer Answer type
* @param integer Student choice
* @param string Textual answer
@ -506,6 +511,7 @@ class ExerciseShowFunctions
* @return void
*/
public static function display_multiple_answer_combination_true_false(
$exercise,
$feedback_type,
$answerType,
$studentChoice,
@ -524,26 +530,22 @@ class ExerciseShowFunctions
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$hide_expected_answer = true;
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = false;
} else {
$hide_expected_answer = true;
}
} ?>
<tr>
<td width="5%">
<?php
//Your choice
}
echo '<tr><td width="5%">';
// Your choice
$question = new MultipleAnswerCombinationTrueFalse();
if (isset($question->options[$studentChoice])) {
echo $question->options[$studentChoice];
} else {
echo $question->options[2];
} ?>
</td>
<td width="5%">
<?php
//Expected choice
}
echo '</td><td width="5%">';
// Expected choice
if (!$hide_expected_answer) {
if (isset($question->options[$answerCorrect])) {
echo $question->options[$answerCorrect];
@ -552,18 +554,28 @@ class ExerciseShowFunctions
}
} else {
echo '-';
} ?>
</td>
<td width="40%">
<?php
//my answer
echo $answer; ?>
</td>
<?php
}
echo '</td>';
echo '<td width="40%">';
// my answer
echo $answer;
echo '</td>';
if ($exercise->showExpectedChoice()) {
$status = '';
if (isset($studentChoice)) {
$status = Display::label(get_lang('Incorrect'), 'danger');
if ($studentChoice == $answerCorrect) {
$status = Display::label(get_lang('Correct'), 'success');
}
}
echo '<td width="20%">';
echo $status;
echo '</td>';
}
if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td width="20%">
<?php
echo '<td width="20%">';
//@todo replace this harcoded value
if ($studentChoice) {
$color = "black";
@ -574,9 +586,8 @@ class ExerciseShowFunctions
$color = '';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
} ?>
</td>
<?php
}
echo '</td>';
if ($ans == 1) {
$comm = Event::get_comments($id, $questionId);
}

@ -760,7 +760,8 @@ ALTER TABLE skill_rel_item ADD CONSTRAINT FK_EB5B2A0D5585C142 FOREIGN KEY (skill
// LP view custom settings
// $_configuration['lp_view_settings'] = ['display' => ['show_reporting_icon' => true]];
// Show more expected choice and status in exercise results BT#13950
//$_configuration['show_exercise_expected_choice'] = false;
// ------ Custom DB changes
// Add user activation by confirmation email

Loading…
Cancel
Save