Question degre de certitude

pull/2485/head
Ivan Zambrano 8 years ago
parent 00f3e4a650
commit 98efe2a62d
  1. 6
      main/exercise/answer.class.php
  2. 487
      main/exercise/exercise.class.php
  3. 172
      main/exercise/exercise_show.php
  4. 79
      main/exercise/exercise_submit.php
  5. 1151
      main/exercise/multiple_answer_true_false_degree_certainty.class.php
  6. 21
      main/exercise/question.class.php
  7. BIN
      main/img/icons/22/mccert.png
  8. BIN
      main/img/icons/22/mccert_na.png
  9. BIN
      main/img/icons/32/mccert.png
  10. BIN
      main/img/icons/64/mccert.png
  11. BIN
      main/img/icons/64/mccert_na.png
  12. 62
      main/inc/ajax/exercise.ajax.php
  13. 83
      main/inc/lib/api.lib.php
  14. 593
      main/inc/lib/exercise.lib.php
  15. 99
      main/inc/lib/exercise_show_functions.lib.php
  16. 148
      main/lang/french/trad4all.inc.php

@ -844,7 +844,8 @@ class Answer
$tableAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE ||
self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE
self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE ||
self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
) {
// Selecting origin options
$origin_options = Question::readQuestionOption(
@ -963,7 +964,8 @@ class Answer
$correct = $this->correct[$i];
if ($newQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE ||
$newQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE
$newQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE ||
$newQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
) {
$correct = $fixed_list[intval($correct)];
}

@ -2846,7 +2846,7 @@ class Exercise
c_id = ".api_get_course_int_id()." AND
exe_exo_id = ".$this->id." AND
session_id = ".api_get_session_id()." ".
$sql_where;
$sql_where;
$result = Database::query($sql);
$exe_list = Database::store_result($result);
@ -3397,12 +3397,16 @@ class Exercise
$totalScore = 0;
// Extra information of the question
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE && !empty($extra)) {
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE ||
$answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY &&
!empty($extra)
) {
$extra = explode(':', $extra);
if ($debug) {
error_log(print_r($extra, 1));
}
// Fixes problems with negatives values using intval
$true_score = floatval(trim($extra[0]));
$false_score = floatval(trim($extra[1]));
$doubt_score = floatval(trim($extra[2]));
@ -3417,6 +3421,12 @@ class Exercise
error_log('$answerType: '.$answerType);
}
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
$choiceTmp = $choice;
$choice = $choiceTmp["choice"];
$choiceDegreeCertainty = $choiceTmp["choiceDegreeCertainty"];
}
if ($answerType == FREE_ANSWER ||
$answerType == ORAL_EXPRESSION ||
$answerType == CALCULATED_ANSWER ||
@ -3565,6 +3575,55 @@ class Exercise
}
$totalScore = $questionScore;
break;
case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY:
if ($from_database) {
$choice = [];
$choiceDegreeCertainty = [];
$sql = "SELECT answer
FROM $TBL_TRACK_ATTEMPT
WHERE
exe_id = $exeId AND question_id = " . $questionId;
$result = Database::query($sql);
while ($row = Database::fetch_array($result)) {
$ind = $row['answer'];
$values = explode(':', $ind);
$myAnswerId = $values[0];
$option = $values[1];
$percent = $values[2];
$choice[$myAnswerId] = $option;
$choiceDegreeCertainty[$myAnswerId] = $percent;
}
}
$studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
$studentChoiceDegree = isset($choiceDegreeCertainty[$answerAutoId]) ? $choiceDegreeCertainty[$answerAutoId] : null;
// student score update
if (!empty($studentChoice)){
if ($studentChoice == $answerCorrect) {
// correct answer and student is Unsure or PrettySur
if ($quiz_question_options[$studentChoiceDegree]['position'] >= 3
&& $quiz_question_options[$studentChoiceDegree]['position'] < 9) {
$questionScore += $true_score;
} else {
// student ignore correct answer
$questionScore += $doubt_score;
}
} else {
// false answer and student is Unsure or PrettySur
if ($quiz_question_options[$studentChoiceDegree]['position'] >= 3
&& $quiz_question_options[$studentChoiceDegree]['position'] < 9) {
$questionScore += $false_score;
} else {
// student ignore correct answer
$questionScore += $doubt_score;
}
}
}
$totalScore = $questionScore;
break;
case MULTIPLE_ANSWER: //2
if ($from_database) {
$choice = [];
@ -3777,12 +3836,12 @@ class Exercise
$choice[$j] = null;
}
} else {
// This value is the user input, not escaped while correct answer is escaped by ckeditor
// This value is the user input, not escaped while correct answer is escaped by fckeditor
$choice[$j] = api_htmlentities(trim($choice[$j]));
}
$user_tags[] = $choice[$j];
// Put the contents of the [] answer tag into correct_tags[]
//put the contents of the [] answer tag into correct_tags[]
$correct_tags[] = api_substr($temp, 0, $pos);
$j++;
$temp = api_substr($temp, $pos + 1);
@ -3790,6 +3849,7 @@ class Exercise
$answer = '';
$real_correct_tags = $correct_tags;
$chosen_list = [];
for ($i = 0; $i < count($real_correct_tags); $i++) {
if ($i == 0) {
$answer .= $real_text[0];
@ -3808,7 +3868,7 @@ class Exercise
// 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>'.$user_tags[$i].'</s></font>';
$answer .= '<font color="red"><s>' . $user_tags[$i] . '</s></font>';
} else {
// adds a tabulation if no word has been typed by the student
$answer .= ''; // remove &nbsp; that causes issue
@ -3975,135 +4035,120 @@ class Exercise
}
break;
case CALCULATED_ANSWER:
$calculatedAnswerList = Session::read('calculatedAnswerId');
if (!empty($calculatedAnswerList)) {
$answer = $objAnswerTmp->selectAnswer($calculatedAnswerList[$questionId]);
$preArray = explode('@@', $answer);
$last = count($preArray) - 1;
$answer = '';
for ($k = 0; $k < $last; $k++) {
$answer .= $preArray[$k];
$answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
$preArray = explode('@@', $answer);
$last = count($preArray) - 1;
$answer = '';
for ($k = 0; $k < $last; $k++) {
$answer .= $preArray[$k];
}
$answerWeighting = [$answerWeighting];
// we save the answer because it will be modified
$temp = $answer;
$answer = '';
$j = 0;
//initialise answer tags
$userTags = $correctTags = $realText = [];
// the loop will stop at the end of the text
while (1) {
// quits the loop if there are no more blanks (detect '[')
if ($temp == false || ($pos = api_strpos($temp, '[')) === false) {
// adds the end of the text
$answer = $temp;
$realText[] = $answer;
break; //no more "blanks", quit the loop
}
// adds the piece of text that is before the blank
//and ends with '[' into a general storage array
$realText[] = api_substr($temp, 0, $pos + 1);
$answer .= api_substr($temp, 0, $pos + 1);
//take the string remaining (after the last "[" we found)
$temp = api_substr($temp, $pos + 1);
// quit the loop if there are no more blanks, and update $pos to the position of next ']'
if (($pos = api_strpos($temp, ']')) === false) {
// adds the end of the text
$answer .= $temp;
break;
}
$answerWeighting = [$answerWeighting];
// we save the answer because it will be modified
$temp = $answer;
$answer = '';
$j = 0;
//initialise answer tags
$userTags = $correctTags = $realText = [];
// the loop will stop at the end of the text
while (1) {
// quits the loop if there are no more blanks (detect '[')
if ($temp == false || ($pos = api_strpos($temp, '[')) === false) {
// adds the end of the text
$answer = $temp;
$realText[] = $answer;
break; //no more "blanks", quit the loop
}
// adds the piece of text that is before the blank
//and ends with '[' into a general storage array
$realText[] = api_substr($temp, 0, $pos + 1);
$answer .= api_substr($temp, 0, $pos + 1);
//take the string remaining (after the last "[" we found)
$temp = api_substr($temp, $pos + 1);
// quit the loop if there are no more blanks, and update $pos to the position of next ']'
if (($pos = api_strpos($temp, ']')) === false) {
// adds the end of the text
$answer .= $temp;
break;
}
if ($from_database) {
$sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
if ($from_database) {
$sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
WHERE
exe_id = '".$exeId."' AND
question_id = ".intval($questionId);
$result = Database::query($sql);
$str = Database::result($result, 0, 'answer');
api_preg_match_all('#\[([^[]*)\]#', $str, $arr);
$str = str_replace('\r\n', '', $str);
$choice = $arr[1];
if (isset($choice[$j])) {
$tmp = api_strrpos($choice[$j], ' / ');
$result = Database::query($sql);
$str = Database::result($result, 0, 'answer');
if ($tmp) {
$choice[$j] = api_substr($choice[$j], 0, $tmp);
} else {
$tmp = ltrim($tmp, '[');
$tmp = rtrim($tmp, ']');
}
api_preg_match_all('#\[([^[]*)\]#', $str, $arr);
$str = str_replace('\r\n', '', $str);
$choice = $arr[1];
if (isset($choice[$j])) {
$tmp = api_strrpos($choice[$j], ' / ');
$choice[$j] = trim($choice[$j]);
// Needed to let characters ' and " to work as part of an answer
$choice[$j] = stripslashes($choice[$j]);
if ($tmp) {
$choice[$j] = api_substr($choice[$j], 0, $tmp);
} else {
$choice[$j] = null;
$tmp = ltrim($tmp, '[');
$tmp = rtrim($tmp, ']');
}
} else {
// This value is the user input, not escaped while correct answer is escaped by fckeditor
$choice[$j] = api_htmlentities(trim($choice[$j]));
}
$userTags[] = $choice[$j];
//put the contents of the [] answer tag into correct_tags[]
$correctTags[] = api_substr($temp, 0, $pos);
$j++;
$temp = api_substr($temp, $pos + 1);
}
$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];
}
// Needed to parse ' and " characters
$userTags[$i] = stripslashes($userTags[$i]);
if ($correctTags[$i] == $userTags[$i]) {
// gives the related weighting to the student
$questionScore += $answerWeighting[$i];
// increments total score
$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>';
$calculatedChoice = $userTags[$i];
$choice[$j] = trim($choice[$j]);
// Needed to let characters ' and " to work as part of an answer
$choice[$j] = stripslashes($choice[$j]);
} else {
// adds a tabulation if no word has been typed by the student
$answer .= ''; // remove &nbsp; that causes issue
$choice[$j] = null;
}
// adds the correct word, followed by ] to close the blank
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 .= ']';
} else {
// This value is the user input, not escaped while correct answer is escaped by fckeditor
$choice[$j] = api_htmlentities(trim($choice[$j]));
}
$userTags[] = $choice[$j];
//put the contents of the [] answer tag into correct_tags[]
$correctTags[] = api_substr($temp, 0, $pos);
$j++;
$temp = api_substr($temp, $pos + 1);
}
$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];
}
// Needed to parse ' and " characters
$userTags[$i] = stripslashes($userTags[$i]);
if ($correctTags[$i] == $userTags[$i]) {
// gives the related weighting to the student
$questionScore += $answerWeighting[$i];
// increments total score
$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>';
$calculatedChoice = $userTags[$i];
} else {
// adds a tabulation if no word has been typed by the student
$answer .= ''; // remove &nbsp; that causes issue
}
// adds the correct word, followed by ] to close the blank
if (isset($realText[$i + 1])) {
$answer .= $realText[$i + 1];
}
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];
}
} else {
if ($from_database) {
$sql = "SELECT *
FROM $TBL_TRACK_ATTEMPT
WHERE
exe_id = $exeId AND
question_id= ".intval($questionId);
$result = Database::query($sql);
$resultData = Database::fetch_array($result, 'ASSOC');
$answer = $resultData['answer'];
$questionScore = $resultData['marks'];
$answer .= ']';
if (isset($realText[$i + 1])) {
$answer .= $realText[$i + 1];
}
}
break;
@ -4624,6 +4669,21 @@ class Exercise
$results_disabled,
$showTotalScoreAndUserChoicesInLastAttempt
);
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){
ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty(
$feedback_type,
$studentChoice,
$studentChoiceDegree,
$answer,
$answerComment,
$answerCorrect,
0,
$questionId,
0,
$results_disabled
);
} elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
ExerciseShowFunctions::display_multiple_answer_combination_true_false(
$this,
@ -5005,6 +5065,35 @@ class Exercise
);
}
break;
case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY :
if ($answerId == 1) {
ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty(
$feedback_type,
$studentChoice,
$studentChoiceDegree,
$answer,
$answerComment,
$answerCorrect,
$exeId,
$questionId,
$answerId,
$results_disabled
);
} else {
ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty(
$feedback_type,
$studentChoice,
$studentChoiceDegree,
$answer,
$answerComment,
$answerCorrect,
$exeId,
$questionId,
"",
$results_disabled
);
}
break;
case FILL_IN_BLANKS:
ExerciseShowFunctions::display_fill_in_blanks_answer(
$feedback_type,
@ -5381,19 +5470,19 @@ class Exercise
<td><b>'.get_lang('Overlap').'</b></td>
<td>'.get_lang('Min').' '.$threadhold1.'</td>
<td><div style="color:'.$overlap_color.'">'
.(($final_overlap < 0) ? 0 : intval($final_overlap)).'</div></td>
.(($final_overlap < 0) ? 0 : intval($final_overlap)).'</div></td>
</tr>
<tr>
<td><b>'.get_lang('Excess').'</b></td>
<td>'.get_lang('Max').' '.$threadhold2.'</td>
<td><div style="color:'.$excess_color.'">'
.(($final_excess < 0) ? 0 : intval($final_excess)).'</div></td>
.(($final_excess < 0) ? 0 : intval($final_excess)).'</div></td>
</tr>
<tr class="row_even">
<td><b>'.get_lang('Missing').'</b></td>
<td>'.get_lang('Max').' '.$threadhold3.'</td>
<td><div style="color:'.$missing_color.'">'
.(($final_missing < 0) ? 0 : intval($final_missing)).'</div></td>
.(($final_missing < 0) ? 0 : intval($final_missing)).'</div></td>
</tr>
</table>';
if ($next == 0) {
@ -5523,9 +5612,11 @@ class Exercise
}
}
//if ($origin != 'learnpath') {
if ($show_result && $answerType != ANNOTATION) {
echo '</table>';
}
// }
}
unset($objAnswerTmp);
@ -5544,21 +5635,43 @@ class Exercise
if (empty($choice)) {
$choice = 0;
}
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
// with certainty degree
if (empty($choiceDegreeCertainty)) {
$choiceDegreeCertainty = 0;
}
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE ||
$answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE ||
$answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
) {
if ($choice != 0) {
$reply = array_keys($choice);
for ($i = 0; $i < sizeof($reply); $i++) {
$ans = $reply[$i];
Event::saveQuestionAttempt(
$questionScore,
$ans.':'.$choice[$ans],
$quesId,
$exeId,
$i,
$this->id
);
$answerChoosen = $reply[$i];
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
if ($choiceDegreeCertainty != 0) {
$replyDegreeCertainty = array_keys($choiceDegreeCertainty);
$answerDegreeCertainty = $replyDegreeCertainty[$i];
Event::saveQuestionAttempt(
$questionScore,
$answerChoosen . ':' . $choice[$answerChoosen] . ':' . $choiceDegreeCertainty[$answerDegreeCertainty],
$quesId,
$exeId,
$i,
$this->id
);
}
} else {
Event::saveQuestionAttempt(
$questionScore,
$answerChoosen.':'.$choice[$answerChoosen],
$quesId,
$exeId,
$i,
$this->id
);
}
if ($debug) {
error_log('result =>'.$questionScore.' '.$ans.':'.$choice[$ans]);
error_log('result =>'.$questionScore.' '.$answerChoosen.':'.$choice[$answerChoosen]);
}
}
} else {
@ -5645,7 +5758,7 @@ class Exercise
) {
$answer = $choice;
Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
// } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
// } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
} elseif ($answerType == HOT_SPOT || $answerType == ANNOTATION) {
$answer = [];
if (isset($exerciseResultCoordinates[$questionId]) && !empty($exerciseResultCoordinates[$questionId])) {
@ -5685,14 +5798,14 @@ class Exercise
}
if ($saved_results) {
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$sql = 'UPDATE '.$table.' SET
exe_result = exe_result + '.floatval($questionScore).'
WHERE exe_id = '.$exeId;
$stat_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$sql = 'UPDATE '.$stat_table.' SET
exe_result = exe_result + ' . floatval($questionScore).'
WHERE exe_id = ' . $exeId;
Database::query($sql);
}
$return = [
$return_array = [
'score' => $questionScore,
'weight' => $questionWeighting,
'extra' => $extra_data,
@ -5702,7 +5815,7 @@ class Exercise
'generated_oral_file' => $generatedFile,
];
return $return;
return $return_array;
}
/**
@ -8040,25 +8153,25 @@ class Exercise
$course_info = api_get_course_info($courseCode);
$msg = get_lang('OpenQuestionsAttempted').'<br /><br />'
.get_lang('AttemptDetails').' : <br /><br />'
.'<table>'
.'<tr>'
.'<td><em>'.get_lang('CourseName').'</em></td>'
.'<td>&nbsp;<b>#course#</b></td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('TestAttempted').'</td>'
.'<td>&nbsp;#exercise#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentName').'</td>'
.'<td>&nbsp;#firstName# #lastName#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentEmail').'</td>'
.'<td>&nbsp;#mail#</td>'
.'</tr>'
.'</table>';
.get_lang('AttemptDetails').' : <br /><br />'
.'<table>'
.'<tr>'
.'<td><em>'.get_lang('CourseName').'</em></td>'
.'<td>&nbsp;<b>#course#</b></td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('TestAttempted').'</td>'
.'<td>&nbsp;#exercise#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentName').'</td>'
.'<td>&nbsp;#firstName# #lastName#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentEmail').'</td>'
.'<td>&nbsp;#mail#</td>'
.'</tr>'
.'</table>';
$open_question_list = null;
foreach ($question_list_answers as $item) {
$question = $item['question'];
@ -8068,19 +8181,19 @@ class Exercise
if (!empty($question) && !empty($answer) && $answer_type == FREE_ANSWER) {
$open_question_list .=
'<tr>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Question').'</td>'
.'<td width="473" valign="top" bgcolor="#F3F3F3">'.$question.'</td>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Question').'</td>'
.'<td width="473" valign="top" bgcolor="#F3F3F3">'.$question.'</td>'
.'</tr>'
.'<tr>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Answer').'</td>'
.'<td valign="top" bgcolor="#F3F3F3">'.$answer.'</td>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Answer').'</td>'
.'<td valign="top" bgcolor="#F3F3F3">'.$answer.'</td>'
.'</tr>';
}
}
if (!empty($open_question_list)) {
$msg .= '<p><br />'.get_lang('OpenQuestionsAttemptedAre').' :</p>'.
'<table width="730" height="136" border="0" cellpadding="3" cellspacing="3">';
'<table width="730" height="136" border="0" cellpadding="3" cellspacing="3">';
$msg .= $open_question_list;
$msg .= '</table><br />';
$msg1 = str_replace("#exercise#", $this->exercise, $msg);
@ -8145,12 +8258,12 @@ class Exercise
}
$oral_question_list .= '<br /><table width="730" height="136" border="0" cellpadding="3" cellspacing="3">'
.'<tr>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Question').'</td>'
.'<td width="473" valign="top" bgcolor="#F3F3F3">'.$question.'</td>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Question').'</td>'
.'<td width="473" valign="top" bgcolor="#F3F3F3">'.$question.'</td>'
.'</tr>'
.'<tr>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Answer').'</td>'
.'<td valign="top" bgcolor="#F3F3F3">'.$answer.$file.'</td>'
.'<td width="220" valign="top" bgcolor="#E5EDF8">&nbsp;&nbsp;'.get_lang('Answer').'</td>'
.'<td valign="top" bgcolor="#F3F3F3">'.$answer.$file.'</td>'
.'</tr></table>';
}
}
@ -8158,24 +8271,24 @@ class Exercise
if (!empty($oral_question_list)) {
$msg = get_lang('OralQuestionsAttempted').'<br /><br />
'.get_lang('AttemptDetails').' : <br /><br />'
.'<table>'
.'<tr>'
.'<td><em>'.get_lang('CourseName').'</em></td>'
.'<td>&nbsp;<b>#course#</b></td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('TestAttempted').'</td>'
.'<td>&nbsp;#exercise#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentName').'</td>'
.'<td>&nbsp;#firstName# #lastName#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentEmail').'</td>'
.'<td>&nbsp;#mail#</td>'
.'</tr>'
.'</table>';
.'<table>'
.'<tr>'
.'<td><em>'.get_lang('CourseName').'</em></td>'
.'<td>&nbsp;<b>#course#</b></td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('TestAttempted').'</td>'
.'<td>&nbsp;#exercise#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentName').'</td>'
.'<td>&nbsp;#firstName# #lastName#</td>'
.'</tr>'
.'<tr>'
.'<td>'.get_lang('StudentEmail').'</td>'
.'<td>&nbsp;#mail#</td>'
.'</tr>'
.'</table>';
$msg .= '<br />'.sprintf(get_lang('OralQuestionsAttemptedAreX'), $oral_question_list).'<br />';
$msg1 = str_replace("#exercise#", $this->exercise, $msg);
$msg = str_replace("#firstName#", $user_info['firstname'], $msg1);

@ -64,6 +64,9 @@ if (empty($exerciseResult)) {
$exerciseResult = Session::read('exerciseResult');
}
if (empty($choiceDegreeCertainty)) {
$choiceDegreeCertainty = isset($_REQUEST['choiceDegreeCertainty']) ? $_REQUEST['choiceDegreeCertainty'] : null;
}
$questionId = isset($_REQUEST['questionId']) ? $_REQUEST['questionId'] : null;
if (empty($choice)) {
@ -87,11 +90,8 @@ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : null;
$courseInfo = api_get_course_info();
$sessionId = api_get_session_id();
$is_allowedToEdit = api_is_allowed_to_edit(null, true) ||
api_is_course_tutor() ||
api_is_session_admin() ||
api_is_drh() ||
api_is_student_boss();
$is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_course_tutor() || api_is_session_admin()
|| api_is_drh() || api_is_student_boss();
if (!empty($sessionId) && !$is_allowedToEdit) {
if (api_is_course_session_coach(
@ -150,6 +150,7 @@ $interbreadcrumb[] = [
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Result')];
$this_section = SECTION_COURSES;
$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>';
@ -222,7 +223,7 @@ if ($action != 'export') {
}
}
</script>
<?php
<?php
}
$show_results = true;
@ -234,41 +235,43 @@ if (!empty($track_exercise_info)) {
// if the results_disabled of the Quiz is 1 when block the script
$result_disabled = $track_exercise_info['results_disabled'];
if ($result_disabled == RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS) {
$show_results = false;
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
$show_results = false;
$show_only_total_score = true;
if ($origin != 'learnpath') {
if ($currentUserId == $student_id) {
echo Display::return_message(
get_lang('ThankYouForPassingTheTest'),
'warning',
false
);
}
}
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$attempts = Event::getExerciseResultsByUser(
$currentUserId,
$objExercise->id,
api_get_course_int_id(),
api_get_session_id(),
$track_exercise_info['orig_lp_id'],
$track_exercise_info['orig_lp_item_id'],
'desc'
);
$numberAttempts = count($attempts);
if ($numberAttempts >= $track_exercise_info['max_attempt']) {
$show_results = true;
if (true) {
if ($result_disabled == RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS) {
$show_results = false;
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
$show_results = false;
$show_only_total_score = true;
// Attempt reach max so show score/feedback now
$showTotalScoreAndUserChoicesInLastAttempt = true;
} else {
$show_results = true;
$show_only_total_score = true;
// Last attempt not reach don't show score/feedback
$showTotalScoreAndUserChoicesInLastAttempt = false;
if ($origin != 'learnpath') {
if ($currentUserId == $student_id) {
echo Display::return_message(
get_lang('ThankYouForPassingTheTest'),
'warning',
false
);
}
}
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$attempts = Event::getExerciseResultsByUser(
$currentUserId,
$objExercise->id,
api_get_course_int_id(),
api_get_session_id(),
$track_exercise_info['orig_lp_id'],
$track_exercise_info['orig_lp_item_id'],
'desc'
);
$numberAttempts = count($attempts);
if ($numberAttempts >= $track_exercise_info['max_attempt']) {
$show_results = true;
$show_only_total_score = true;
// Attempt reach max so show score/feedback now
$showTotalScoreAndUserChoicesInLastAttempt = true;
} else {
$show_results = true;
$show_only_total_score = true;
// Last attempt not reach don't show score/feedback
$showTotalScoreAndUserChoicesInLastAttempt = false;
}
}
}
} else {
@ -323,11 +326,11 @@ $sql = "SELECT attempts.question_id, answer
attempts.exe_id = ".intval($id)." $user_restriction
GROUP BY quizz_rel_questions.question_order, attempts.question_id";
$result = Database::query($sql);
$questionListFromDatabase = [];
$question_list_from_database = [];
$exerciseResult = [];
while ($row = Database::fetch_array($result)) {
$questionListFromDatabase[] = $row['question_id'];
$question_list_from_database[] = $row['question_id'];
$exerciseResult[$row['question_id']] = $row['answer'];
}
@ -341,16 +344,16 @@ if (!empty($track_exercise_info['data_tracking'])) {
}
// If for some reason data_tracking is empty we select the question list from db
if (empty($questionList)) {
$questionList = $questionListFromDatabase;
$questionList = $question_list_from_database;
}
} else {
$questionList = $questionListFromDatabase;
$questionList = $question_list_from_database;
}
// Display the text when finished message if we are on a LP #4227
$endOfMessage = $objExercise->selectTextWhenFinished();
if (!empty($endOfMessage) && ($origin == 'learnpath')) {
echo Display::return_message($endOfMessage, 'normal', false);
$end_of_message = $objExercise->selectTextWhenFinished();
if (!empty($end_of_message) && ($origin == 'learnpath')) {
echo Display::return_message($end_of_message, 'normal', false);
echo "<div class='clear'>&nbsp;</div>";
}
@ -367,6 +370,7 @@ $counter = 1;
$exercise_content = '';
$category_list = [];
$useAdvancedEditor = true;
if (!empty($maxEditors) && count($questionList) > $maxEditors) {
$useAdvancedEditor = false;
}
@ -430,6 +434,25 @@ foreach ($questionList as $questionId) {
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
break;
case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY:
$choiceTmp = [];
$choiceTmp["choice"] = $choice;
$choiceTmp["choiceDegreeCertainty"] = $choiceDegreeCertainty;
$questionResult = $objExercise->manage_answer(
$id,
$questionId,
$choiceTmp,
'exercise_show',
[],
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
);
$questionScore = $questionResult['score'];
$totalScore += $questionResult['score'];
break;
case HOT_SPOT:
if ($show_results || $showTotalScoreAndUserChoicesInLastAttempt) {
echo '<table width="500" border="0"><tr>
@ -757,6 +780,8 @@ foreach ($questionList as $questionId) {
}
$feedback_form->setDefaults($default);
$feedback_form->display();
echo '</div>';
if ($allowRecordAudio && $allowTeacherCommentAudio) {
@ -923,31 +948,46 @@ foreach ($questionList as $questionId) {
$exercise_content .= Display::panel($question_content);
} // end of large foreach on questions
$total_score_text = '';
$totalScoreText = '';
//Total score
if ($origin != 'learnpath' || ($origin == 'learnpath' && isset($_GET['fb_type']))) {
if ($show_results || $show_only_total_score || $showTotalScoreAndUserChoicesInLastAttempt) {
$total_score_text .= '<div class="question_row">';
$my_total_score_temp = $totalScore;
if ($objExercise->selectPropagateNeg() == 0 && $my_total_score_temp < 0) {
$my_total_score_temp = 0;
$totalScoreText .= '<div class="question_row">';
$myTotalScoreTemp = $totalScore;
if ($objExercise->selectPropagateNeg() == 0 && $myTotalScoreTemp < 0) {
$myTotalScoreTemp = 0;
}
$total_score_text .= ExerciseLib::getTotalScoreRibbon(
$objExercise,
$my_total_score_temp,
$totalWeighting,
true,
$countPendingQuestions
);
$total_score_text .= '</div>';
if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
$totalScoreText .= ExerciseLib::getQuestionRibbonDiag(
$objExercise,
$myTotalScoreTemp,
$totalWeighting,
true
);
} else{
$totalScoreText .= ExerciseLib::getTotalScoreRibbon(
$objExercise,
$myTotalScoreTemp,
$totalWeighting,
true,
$countPendingQuestions
);
}
$totalScoreText .= '</div>';
}
}
if ( $answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){
$chartMultiAnswer = MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults($id, $objExercise);
echo $chartMultiAnswer;
}
if (!empty($category_list) && ($show_results || $show_only_total_score || $showTotalScoreAndUserChoicesInLastAttempt)) {
// Adding total
$category_list['total'] = [
'score' => $my_total_score_temp,
'score' => $myTotalScoreTemp,
'total' => $totalWeighting,
];
echo TestCategory::get_stats_table_by_attempt(
@ -956,12 +996,12 @@ if (!empty($category_list) && ($show_results || $show_only_total_score || $showT
);
}
echo $total_score_text;
echo $totalScoreText;
echo $exercise_content;
// only show "score" in bottom of page if there's exercise content
if ($show_results) {
echo $total_score_text;
echo $totalScoreText;
}
if ($action == 'export') {
@ -1090,14 +1130,14 @@ if ($origin == 'student_progress') {
</button>
<?php
} elseif ($origin == 'myprogress') {
?>
?>
<button type="button" class="save"
onclick="top.location.href='../auth/my_progress.php?course=<?php echo api_get_course_id(); ?>'"
value="<?php echo get_lang('Finish'); ?>">
<?php echo get_lang('Finish'); ?>
</button>
<?php
}
}
if ($origin != 'learnpath') {
//we are not in learnpath tool
@ -1135,5 +1175,3 @@ unset($questionList);
Session::erase('exerciseResult');
unset($exerciseResult);
Session::erase('calculatedAnswerId');

@ -786,7 +786,64 @@ if ($question_count != 0) {
header('Location: exercise_reminder.php?'.$params);
exit;
} else {
header("Location: exercise_result.php?".api_get_cidreq()."&exe_id=$exe_id&learnpath_id=$learnpath_id&learnpath_item_id=$learnpath_item_id&learnpath_item_view_id=$learnpath_item_view_id");
// Question degree certainty
// We send un email to the student before redirection to the result page
$userInfo = api_get_user_info($user_id);
$recipient_name = api_get_person_name($userInfo['firstname'],
$userInfo['lastname'],
null,
PERSON_NAME_EMAIL_ADDRESS
);
$emailTo = $userInfo['email'];
$senderName = api_get_person_name(api_get_setting('administratorName'),
api_get_setting('administratorSurname'),
null,
PERSON_NAME_EMAIL_ADDRESS
);
$emailGenerique = api_get_setting('emailAdministrator');
$subject = "[" . get_lang('DoNotReply') . "] "
. html_entity_decode(get_lang('ResultAccomplishedTest')." \"" . $objExercise->title . "\"");
// message sended to the student
$message = get_lang('Dear') . ' ' . $recipient_name . ",<br><br>";
//calcul du chemmin sans les script php
$url = $_SERVER['SCRIPT_NAME'];
$pos = strripos($url, "/");
$path = substr($url, 0, $pos);
$message .= get_lang('MessageQuestionCertainty');
$exerciseLink = "<a href='" . api_get_path(WEB_CODE_PATH) . "/exercise/result.php?show_headers=1&"
. api_get_cidreq()
. "&id=$exe_id'>";
$titleExercice = $objExercise->title;
$message = str_replace('%exerTitle', $titleExercice, $message);
$message = str_replace('%webPath', api_get_path(WEB_PATH), $message);
$message = str_replace('%s', $exerciseLink, $message);
// show histogram
require_once api_get_path(SYS_CODE_PATH)
. "exercise/multiple_answer_true_false_degree_certainty.class.php";
$message .= MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults($exe_id, $objExercise);
$message .= get_lang('KindRegards');
$message = api_preg_replace("/\\\n/", "", $message);
api_mail_html($recipient_name,
$emailTo,
$subject,
$message,
$senderName,
$emailGenerique,
['content-type' => 'html']
);
header("Location: exercise_result.php?"
. api_get_cidreq()
. "&exe_id=$exe_id&learnpath_id=$learnpath_id&learnpath_item_id="
. $learnpath_item_id
. "&learnpath_item_view_id=$learnpath_item_view_id"
);
exit;
}
}
@ -1041,6 +1098,8 @@ if (!empty($error)) {
$onsubmit = "onsubmit=\"return validateFlashVar('".$number_of_hotspot_questions."', '".get_lang('HotspotValidateError1')."', '".get_lang('HotspotValidateError2')."');\"";
}
$saveIcon = Display::return_icon(
'save.png',
get_lang('Saved'),
@ -1081,7 +1140,7 @@ if (!empty($error)) {
}
$(function() {
// This pre-load the save.png icon
//This pre-load the save.png icon
var saveImage = new Image();
saveImage.src = "'.$saveIcon.'";
@ -1109,10 +1168,11 @@ if (!empty($error)) {
});*/
$("form#exercise_form").prepend($("#exercise-description"));
$(\'button[name="previous_question_and_save"]\').on("click", function (e) {
e.preventDefault();
e.stopPropagation();
e.stopPropagation();
var
$this = $(this),
previousId = parseInt($this.data(\'prev\')) || 0,
@ -1132,7 +1192,8 @@ if (!empty($error)) {
$(\'button[name="save_now"]\').on(\'click\', function (e) {
e.preventDefault();
e.stopPropagation();
e.stopPropagation();
var
$this = $(this),
questionId = parseInt($this.data(\'question\')) || 0,
@ -1143,7 +1204,8 @@ if (!empty($error)) {
$(\'button[name="validate_all"]\').on(\'click\', function (e) {
e.preventDefault();
e.stopPropagation();
e.stopPropagation();
validate_all();
});
@ -1190,6 +1252,9 @@ if (!empty($error)) {
//3. Hotspots
var hotspot = $(\'*[name*="hotspot[\'+question_id+\']"]\').serialize();
//4. choice for degree of certainty
var myChoiceDegreeCertainty = $(\'*[name*="choiceDegreeCertainty[\'+question_id+\']"]\').serialize();
// Checking FCK
if (question_id) {
if (CKEDITOR.instances["choice["+question_id+"]"]) {
@ -1213,7 +1278,7 @@ if (!empty($error)) {
type:"post",
async: false,
url: "'.api_get_path(WEB_AJAX_PATH).'exercise.ajax.php?'.api_get_cidreq().'&a=save_exercise_by_now",
data: "'.$params.'&type=simple&question_id="+question_id+"&"+my_choice+"&"+hotspot+"&"+remind_list,
data: "'.$params.'&type=simple&question_id="+question_id+"&"+my_choice+"&"+hotspot+"&"+remind_list+"&"+myChoiceDegreeCertainty,
success: function(return_value) {
if (return_value == "ok") {
$("#save_for_now_"+question_id).html(\''.Display::return_icon('save.png', get_lang('Saved'), [], ICON_SIZE_SMALL).'\');

@ -50,6 +50,10 @@ abstract class Question
MULTIPLE_ANSWER_COMBINATION => ['multiple_answer_combination.class.php', 'MultipleAnswerCombination'],
UNIQUE_ANSWER_NO_OPTION => ['unique_answer_no_option.class.php', 'UniqueAnswerNoOption'],
MULTIPLE_ANSWER_TRUE_FALSE => ['multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'],
MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY => [
'multiple_answer_true_false_degree_certainty.class.php',
'MultipleAnswerTrueFalseDegreeCertainty'
],
MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE => [
'multiple_answer_combination_true_false.class.php',
'MultipleAnswerCombinationTrueFalse',
@ -1519,12 +1523,13 @@ abstract class Question
public static function getInstance($type)
{
if (!is_null($type)) {
list($file_name, $class_name) = self::get_question_type($type);
if (!empty($file_name)) {
if (class_exists($class_name)) {
return new $class_name();
list($fileName, $className) = self::get_question_type($type);
if (!empty($fileName)) {
include_once $fileName;
if (class_exists($className)) {
return new $className();
} else {
echo 'Can\'t instanciate class '.$class_name.' of type '.$type;
echo 'Can\'t instanciate class '.$className.' of type '.$type;
}
}
}
@ -1980,7 +1985,11 @@ abstract class Question
'missing' => $score['weight'],
];
$header .= Display::page_subheader2($counterLabel.'. '.$this->question);
$header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent);
// dont display score for certainty degree questions
if($this->type != MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
$header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent);
}
if ($this->type != READING_COMPREHENSION) {
// Do not show the description (the text to read) if the question is of type READING_COMPREHENSION
$header .= Display::div(

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -12,6 +12,7 @@ api_protect_course_script(true);
$action = $_REQUEST['a'];
$course_id = api_get_course_int_id();
if ($debug) {
error_log("-----------------");
error_log("$action ajax call");
@ -275,14 +276,14 @@ switch ($action) {
$h = floor($remaining / 3600);
$m = floor(($remaining - ($h * 3600)) / 60);
$s = ($remaining - ($h * 3600) - ($m * 60));
$timeInfo = api_format_date(
$row['start_date'],
DATE_TIME_FORMAT_LONG
).' ['.($h > 0 ? $h.':' : '').sprintf("%02d", $m).':'.sprintf("%02d", $s).']';
} else {
$timeInfo = api_format_date(
$row['start_date'],
DATE_TIME_FORMAT_LONG
).' ['.($h > 0 ? $h.':' : '').sprintf("%02d", $m).':'.sprintf("%02d", $s).']';
} else {
$timeInfo = api_format_date(
$row['start_date'],
DATE_TIME_FORMAT_LONG
);
}
$array = [
@ -380,6 +381,9 @@ switch ($action) {
// Questions choices.
$choice = isset($_REQUEST['choice']) ? $_REQUEST['choice'] : null;
// cretainty degree choice
$choiceDegreeCertainty = isset($_REQUEST['choiceDegreeCertainty']) ? $_REQUEST['choiceDegreeCertainty'] : null;
// Hot spot coordinates from all questions.
$hot_spot_coordinates = isset($_REQUEST['hotspot']) ? $_REQUEST['hotspot'] : null;
@ -503,6 +507,11 @@ switch ($action) {
// Creates a temporary Question object
$objQuestionTmp = Question::read($my_question_id, $course_id);
if ($objQuestionTmp->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
// LQ debug
$myChoiceDegreeCertainty = isset($choiceDegreeCertainty[$my_question_id]) ? $choiceDegreeCertainty[$my_question_id] : null;
}
// Getting free choice data.
if (in_array($objQuestionTmp->type, [FREE_ANSWER, ORAL_EXPRESSION]) && $type == 'all') {
$my_choice = isset($_REQUEST['free_choice'][$my_question_id]) && !empty($_REQUEST['free_choice'][$my_question_id])
@ -570,18 +579,37 @@ switch ($action) {
}
// We're inside *one* question. Go through each possible answer for this question
$result = $objExercise->manage_answer(
$exeId,
$my_question_id,
$my_choice,
'exercise_result',
$hot_spot_coordinates,
true,
false,
false,
$objExercise->selectPropagateNeg(),
$hotspot_delineation_result
);
if ($objQuestionTmp->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
$myChoiceTmp = [];
$myChoiceTmp["choice"] = $my_choice;
$myChoiceTmp["choiceDegreeCertainty"] = $myChoiceDegreeCertainty;
$result = $objExercise->manage_answer(
$exeId,
$my_question_id,
$myChoiceTmp,
'exercise_result',
$hot_spot_coordinates,
true,
false,
false,
$objExercise->selectPropagateNeg(),
$hotspot_delineation_result
);
} else {
$result = $objExercise->manage_answer(
$exeId,
$my_question_id,
$my_choice,
'exercise_result',
$hot_spot_coordinates,
true,
false,
false,
$objExercise->selectPropagateNeg(),
$hotspot_delineation_result
);
}
// Adding the new score.
$total_score += $result['score'];

@ -485,6 +485,7 @@ define('DRAGGABLE', 18);
define('MATCHING_DRAGGABLE', 19);
define('ANNOTATION', 20);
define('READING_COMPREHENSION', 21);
define('MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY', 22);
define('EXERCISE_CATEGORY_RANDOM_SHUFFLED', 1);
define('EXERCISE_CATEGORY_RANDOM_ORDERED', 2);
@ -536,6 +537,7 @@ define(
UNIQUE_ANSWER_IMAGE.':'.
DRAGGABLE.':'.
MATCHING_DRAGGABLE.':'.
MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY.':'.
ANNOTATION
);
@ -742,12 +744,12 @@ function api_get_path($path = '', $configuration = [])
if (isset($_SERVER['SERVER_PORT']) &&
!strpos($server_name, ':') &&
(($server_protocol == 'http' && $_SERVER['SERVER_PORT'] != 80) ||
($server_protocol == 'https' && $_SERVER['SERVER_PORT'] != 443))
($server_protocol == 'https' && $_SERVER['SERVER_PORT'] != 443))
) {
$server_name .= ":".$_SERVER['SERVER_PORT'];
}
$root_web = $server_protocol.'://'.$server_name.$root_rel;
$root_sys = str_replace('\\', '/', realpath(__DIR__.'/../../../')).'/';
$root_sys = str_replace('\\', '/', realpath(__DIR__ . '/../../ficher test degre certitudes/')).'/';
}
// Here we give up, so we don't touch anything.
}
@ -2024,7 +2026,7 @@ function api_get_course_info($course_code = null, $strict = false)
*
* @return \Chamilo\CoreBundle\Entity\Course
*/
function api_get_course_entity($courseId = 0)
function api_get_course_entity($courseId)
{
if (empty($courseId)) {
$courseId = api_get_course_int_id();
@ -2033,20 +2035,6 @@ function api_get_course_entity($courseId = 0)
return Database::getManager()->getRepository('ChamiloCoreBundle:Course')->find($courseId);
}
/**
* @param int $id
*
* @return \Chamilo\CoreBundle\Entity\Session
*/
function api_get_session_entity($id = 0)
{
if (empty($id)) {
$id = api_get_session_id();
}
return Database::getManager()->getRepository('ChamiloCoreBundle:Session')->find($id);
}
/**
* Returns the current course info array.
@ -2180,8 +2168,7 @@ function api_format_course_array($course_data)
null,
null,
null,
true,
false
true
);
}
$_course['course_image_large'] = $url_image;
@ -2598,11 +2585,11 @@ function api_get_session_image($session_id, $status_id)
if ((int) $status_id != 5) { //check whether is not a student
if ($session_id > 0) {
$session_img = "&nbsp;&nbsp;".Display::return_icon(
'star.png',
get_lang('SessionSpecificResource'),
['align' => 'absmiddle'],
ICON_SIZE_SMALL
);
'star.png',
get_lang('SessionSpecificResource'),
['align' => 'absmiddle'],
ICON_SIZE_SMALL
);
}
}
@ -2732,11 +2719,6 @@ function api_get_settings_params($params)
return $result;
}
/**
* @param array $params example: [id = ? => '1']
*
* @return array
*/
function api_get_settings_params_simple($params)
{
$table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
@ -2974,7 +2956,7 @@ function api_is_coach($session_id = 0, $courseId = null, $check_student_view = t
$session_table = Database::get_main_table(TABLE_MAIN_SESSION);
$session_rel_course_rel_user_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
$sessionIsCoach = [];
$sessionIsCoach = null;
if (!empty($courseId)) {
$sql = "SELECT DISTINCT s.id, name, access_start_date, access_end_date
@ -3257,6 +3239,10 @@ function api_is_allowed_to_edit(
$session_coach = false,
$check_student_view = true
) {
$sessionId = api_get_session_id();
$is_allowed_coach_to_edit = api_is_coach(null, null, $check_student_view);
$session_visibility = api_get_session_visibility($sessionId);
// Admins can edit anything.
if (api_is_platform_admin(false)) {
//The student preview was on
@ -3267,9 +3253,6 @@ function api_is_allowed_to_edit(
}
}
$sessionId = api_get_session_id();
$is_allowed_coach_to_edit = api_is_coach(null, null, $check_student_view);
$session_visibility = api_get_session_visibility($sessionId);
$is_courseAdmin = api_is_course_admin();
if (!$is_courseAdmin && $tutor) {
@ -4895,9 +4878,9 @@ function api_get_visual_theme()
}
$course_id = api_get_course_id();
if (!empty($course_id)) {
if (!empty($course_id) && $course_id != -1) {
if (api_get_setting('allow_course_theme') == 'true') {
$course_theme = api_get_course_setting('course_theme', $course_id);
$course_theme = api_get_course_setting('course_theme');
if (!empty($course_theme) && $course_theme != -1) {
if (!empty($course_theme)) {
@ -5670,10 +5653,10 @@ function api_set_setting($var, $value, $subvar = null, $cat = null, $access_url
$insert = "INSERT INTO $t_settings (variable, subkey, type,category, selected_value, title, comment, scope, subkeytext, access_url)
VALUES
('".$row['variable']."',".(!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL").",".
"'".$row['type']."','".$row['category']."',".
"'$value','".$row['title']."',".
"".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".(!empty($row['scope']) ? "'".$row['scope']."'" : "NULL").",".
"".(!empty($row['subkeytext']) ? "'".$row['subkeytext']."'" : "NULL").",$access_url)";
"'".$row['type']."','".$row['category']."',".
"'$value','".$row['title']."',".
"".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".(!empty($row['scope']) ? "'".$row['scope']."'" : "NULL").",".
"".(!empty($row['subkeytext']) ? "'".$row['subkeytext']."'" : "NULL").",$access_url)";
Database::query($insert);
} else {
// Such a setting does not exist.
@ -5695,12 +5678,12 @@ function api_set_setting($var, $value, $subvar = null, $cat = null, $access_url
if ($row['access_url_changeable'] == 1) {
$insert = "INSERT INTO $t_settings (variable,subkey, type,category, selected_value,title, comment,scope, subkeytext,access_url, access_url_changeable) VALUES
('".$row['variable']."',".
(!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL").",".
"'".$row['type']."','".$row['category']."',".
"'$value','".$row['title']."',".
"".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".
(!empty($row['scope']) ? "'".$row['scope']."'" : "NULL").",".
"".(!empty($row['subkeytext']) ? "'".$row['subkeytext']."'" : "NULL").",$access_url,".$row['access_url_changeable'].")";
(!empty($row['subkey']) ? "'".$row['subkey']."'" : "NULL").",".
"'".$row['type']."','".$row['category']."',".
"'$value','".$row['title']."',".
"".(!empty($row['comment']) ? "'".$row['comment']."'" : "NULL").",".
(!empty($row['scope']) ? "'".$row['scope']."'" : "NULL").",".
"".(!empty($row['subkeytext']) ? "'".$row['subkeytext']."'" : "NULL").",$access_url,".$row['access_url_changeable'].")";
Database::query($insert);
}
} else { // Such a setting does not exist.
@ -6177,7 +6160,6 @@ function api_is_element_in_the_session($tool, $element_id, $session_id = null)
return true;
}
}
return false;
}
@ -9038,18 +9020,17 @@ function api_float_val($number)
* 3.141516 => 3.14
* 3,141516 => 3,14
*
* @todo WIP
*
* @param string $number number in iso code
* @param int $decimals
* @param string $decimalSeparator
* @param string $thousandSeparator
*
* @return bool|string
*/
function api_number_format($number, $decimals = 0, $decimalSeparator = '.', $thousandSeparator = ',')
function api_number_format($number, $decimals = 0)
{
$number = api_float_val($number);
return number_format($number, $decimals, $decimalSeparator, $thousandSeparator);
return number_format($number, $decimals);
}
/**

@ -98,7 +98,7 @@ class ExerciseLib
// construction of the Answer object (also gets all answers details)
$objAnswerTmp = new Answer($questionId, api_get_course_int_id(), $exercise);
$nbrAnswers = $objAnswerTmp->selectNbrAnswers();
$quiz_question_options = Question::readQuestionOption(
$quizQuestionOptions = Question::readQuestionOption(
$questionId,
$course_id
);
@ -248,6 +248,182 @@ class ExerciseLib
$header,
['style' => 'text-align:left;']
);
} else if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){
echo "<script>
function RadioValidator(question_id, answer_id)
{
var ShowAlert = \"\";
var typeRadioB = \"\";
var AllFormElements = window.document.getElementById(\"exercise_form\").elements;
for (i = 0; i < AllFormElements.length; i++) {
if (AllFormElements[i].type == \"radio\") {
var ThisRadio = AllFormElements[i].name;
var ThisChecked = \"No\";
var AllRadioOptions = document.getElementsByName(ThisRadio);
for (x = 0; x < AllRadioOptions.length; x++) {
if (AllRadioOptions[x].checked && ThisChecked == \"No\") {
ThisChecked = \"Yes\";
break;
}
}
var AlreadySearched = ShowAlert.indexOf(ThisRadio);
if (ThisChecked == \"No\" && AlreadySearched == -1) {
ShowAlert = ShowAlert + ThisRadio;
}
}
}
if (ShowAlert != \"\") {
} else {
$(\".question-validate-btn\").attr(\"onclick\", \"save_now (\" + question_id +\", '', \" + answer_id+\")\");
$(\".question-validate-btn\").removeAttr('disabled');
}
}
function handleRadioRow(event, question_id, answer_id) {
var t = event.target;
if (t && t.tagName == \"INPUT\")
return;
while (t && t.tagName != \"TD\") {
t = t.parentElement;
}
var r = t.getElementsByTagName(\"INPUT\")[0];
r.click();
RadioValidator(question_id, answer_id);
}
$( document ).ready(function() {
var ShowAlert = \"\";
var typeRadioB = \"\";
var question_id = $('input[name=question_id]').val()
var AllFormElements = window.document.getElementById(\"exercise_form\").elements;
for (i = 0; i < AllFormElements.length; i++) {
if (AllFormElements[i].type == \"radio\") {
var ThisRadio = AllFormElements[i].name;
var ThisChecked = \"No\";
var AllRadioOptions = document.getElementsByName(ThisRadio);
for (x = 0; x < AllRadioOptions.length; x++) {
if (AllRadioOptions[x].checked && ThisChecked == \"No\") {
ThisChecked = \"Yes\";
break;
}
}
var AlreadySearched = ShowAlert.indexOf(ThisRadio);
if (ThisChecked == \"No\" && AlreadySearched == -1) {
ShowAlert = ShowAlert + ThisRadio;
}
}
}
if (ShowAlert != \"\") {
$(\".question-validate-btn\").attr(\"onclick\", \"\");
$(\".question-validate-btn\").attr(\"disabled\", \"disabled\");
} else {
$(\".question-validate-btn\").attr(\"onclick\", \"save_now(\" + question_id +\", '', '')\");
$(\".question-validate-btn\").removeAttr('disabled');
}
});
</script>";
$header = Display::tag('th', get_lang('Options'), array('width' => '50%'));
foreach ($objQuestionTmp->optionsTitle as $item) {
if (in_array($item, $objQuestionTmp->optionsTitle)) {
$properties = array();
if ($item == "langAnswers") {
$properties["colspan"] = 2;
$properties["style"] = "background-color: #F56B2A; color: #ffffff;";
} else if ($item == "DegreeOfCertainty") {
$properties["colspan"] = 6;
$properties["style"] = "background-color: #330066; color: #ffffff;";
}
$header .= Display::tag('th', get_lang($item), $properties);
} else {
$header .= Display::tag('th', $item);
}
}
if ($show_comment) {
$header .= Display::tag('th', get_lang('Feedback'));
}
$s .= '<table class="data_table">';
$s .= Display::tag('tr', $header, ['style' => 'text-align:left;']);
// ajout de la 2eme ligne d'entête pour true/falss et les pourcentages de certitude
$header1 = Display::tag('th', '&nbsp;');
$cpt1 = 0;
foreach ($objQuestionTmp->options as $item) {
$colorBorder1 =($cpt1 == (count($objQuestionTmp->options)-1))?'':'border-right: solid #FFFFFF 1px;' ;
if ($item == "True" || $item == "False") {
$header1 .= Display::tag('th',
get_lang($item),
['style' => 'background-color: #F7C9B4; color: black;'. $colorBorder1]
);
} else {
$header1 .= Display::tag('th',
$item,
['style' => 'background-color: #e6e6ff; color: black;padding:5px; '.$colorBorder1]);
}
$cpt1++;
}
if ($show_comment) {
$header1 .= Display::tag('th', '&nbsp;');
}
$s .= Display::tag('tr', $header1);
// add explanation
$header2 = Display::tag('th', '&nbsp;');
$descriptionList = [
get_lang('Ignorance'),
get_lang('VeryUnsure'),
get_lang('Unsure'),
get_lang('PrettySur'),
get_lang('Sur'),
get_lang('VerySur')
];
$counter2 = 0;
foreach ($objQuestionTmp->options as $item) {
if ($item == "True" || $item == "False") {
$header2 .= Display::tag('td',
'&nbsp;',
['style' => 'background-color: #F7E1D7; color: black;border-right: solid #FFFFFF 1px;']);
} else {
$color_border2 =($counter2 == (count($objQuestionTmp->options)-1)) ? '' : 'border-right: solid #FFFFFF 1px;font-size:11px;' ;
$header2 .= Display::tag(
'td',
nl2br($descriptionList[$counter2]),
array('style' => 'background-color: #EFEFFC; color: black; width: 110px; text-align:center; vertical-align: top; padding:5px; '.$color_border2));
$counter2++;
}
}
if ($show_comment) {
$header2 .= Display::tag('th', '&nbsp;');
}
$s .= Display::tag('tr', $header2);
}
if ($show_comment) {
@ -276,10 +452,10 @@ class ExerciseLib
}
$matching_correct_answer = 0;
$user_choice_array = [];
$userChoiceList = [];
if (!empty($user_choice)) {
foreach ($user_choice as $item) {
$user_choice_array[] = $item['answer'];
$userChoiceList[] = $item['answer'];
}
}
@ -384,13 +560,14 @@ class ExerciseLib
$s .= $answer_input;
}
break;
case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY:
case MULTIPLE_ANSWER:
case MULTIPLE_ANSWER_TRUE_FALSE:
case GLOBAL_MULTIPLE_ANSWER:
$input_id = 'choice-'.$questionId.'-'.$answerId;
$answer = Security::remove_XSS($answer, STUDENT);
if (in_array($numAnswer, $user_choice_array)) {
if (in_array($numAnswer, $userChoiceList)) {
$attributes = [
'id' => $input_id,
'checked' => 1,
@ -432,20 +609,20 @@ class ExerciseLib
$s .= $answer_input;
}
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
$my_choice = [];
if (!empty($user_choice_array)) {
foreach ($user_choice_array as $item) {
$myChoice = [];
if (!empty($userChoiceList)) {
foreach ($userChoiceList as $item) {
$item = explode(':', $item);
$my_choice[$item[0]] = $item[1];
$myChoice[$item[0]] = $item[1];
}
}
$s .= '<tr>';
$s .= Display::tag('td', $answer);
if (!empty($quiz_question_options)) {
foreach ($quiz_question_options as $id => $item) {
if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) {
if (!empty($quizQuestionOptions)) {
foreach ($quizQuestionOptions as $id => $item) {
if (isset($myChoice[$numAnswer]) && $id == $myChoice[$numAnswer]) {
$attributes = [
'checked' => 1,
'selected' => 1,
@ -479,13 +656,89 @@ class ExerciseLib
$s .= '</td>';
}
$s .= '</tr>';
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){
$myChoice = [];
if (!empty($userChoiceList)) {
foreach ($userChoiceList as $item) {
$item = explode(':', $item);
$myChoice[$item[0]] = $item[1];
}
}
$myChoiceDegreeCertainty = [];
if (!empty($userChoiceList)) {
foreach ($userChoiceList as $item) {
$item = explode(':', $item);
$myChoiceDegreeCertainty[$item[0]] = $item[2];
}
}
$s .= '<tr>';
$s .= Display::tag('td', $answer);
if (!empty($quizQuestionOptions)) {
foreach ($quizQuestionOptions as $id => $item) {
if (isset($myChoice[$numAnswer]) && $id == $myChoice[$numAnswer]) {
$attributes = ['checked' => 1, 'selected' => 1];
} else {
$attributes = [];
}
$attributes['onChange'] = 'RadioValidator(' . $questionId . ', ' . $numAnswer . ')';
// gère la séletion des radio button du degré de certitude
if (isset($myChoiceDegreeCertainty[$numAnswer]) && $id == $myChoiceDegreeCertainty[$numAnswer]) {
$attributes1 = ['checked' => 1, 'selected' => 1];
} else {
$attributes1 = [];
}
$attributes1['onChange'] = 'RadioValidator(' . $questionId . ', ' . $numAnswer . ')';
if ($debug_mark_answer) {
if ($id == $answerCorrect) {
$attributes['checked'] = 1;
$attributes['selected'] = 1;
}
}
if ($item["name"] == "True" || $item["name"] == "False") {
$s .= Display::tag('td',
Display::input('radio',
'choice[' . $questionId . '][' . $numAnswer . ']',
$id,
$attributes
),
['style' => 'text-align:center; background-color:#F7E1D7;',
'onclick' => 'handleRadioRow(event, ' . $questionId . ', ' . $numAnswer . ')'
]
);
} else {
$s .= Display::tag('td',
Display::input('radio',
'choiceDegreeCertainty[' . $questionId . '][' . $numAnswer . ']',
$id,
$attributes1
),
['style' => 'text-align:center; background-color:#EFEFFC;',
'onclick' => 'handleRadioRow(event, ' . $questionId . ', ' . $numAnswer . ')'
]
);
}
}
}
if ($show_comment) {
$s .= '<td>';
$s .= $comment;
$s .= '</td>';
}
$s.='</tr>';
}
break;
case MULTIPLE_ANSWER_COMBINATION:
// multiple answers
$input_id = 'choice-'.$questionId.'-'.$answerId;
if (in_array($numAnswer, $user_choice_array)) {
if (in_array($numAnswer, $userChoiceList)) {
$attributes = [
'id' => $input_id,
'checked' => 1,
@ -529,12 +782,12 @@ class ExerciseLib
break;
case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
$s .= '<input type="hidden" name="choice2['.$questionId.']" value="0" />';
$my_choice = [];
if (!empty($user_choice_array)) {
foreach ($user_choice_array as $item) {
$myChoice = [];
if (!empty($userChoiceList)) {
foreach ($userChoiceList as $item) {
$item = explode(':', $item);
if (isset($item[1]) && isset($item[0])) {
$my_choice[$item[0]] = $item[1];
$myChoice[$item[0]] = $item[1];
}
}
}
@ -542,7 +795,7 @@ class ExerciseLib
$s .= '<tr>';
$s .= Display::tag('td', $answer);
foreach ($objQuestionTmp->options as $key => $item) {
if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) {
if (isset($myChoice[$numAnswer]) && $key == $myChoice[$numAnswer]) {
$attributes = [
'checked' => 1,
'selected' => 1,
@ -663,16 +916,18 @@ class ExerciseLib
global $exe_id;
$trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$sql = 'SELECT answer FROM '.$trackAttempts.'
WHERE exe_id='.$exe_id.' AND question_id='.$questionId;
WHERE exe_id=' . $exe_id.' AND question_id='.$questionId;
$rsLastAttempt = Database::query($sql);
$rowLastAttempt = Database::fetch_array($rsLastAttempt);
$answer = $rowLastAttempt['answer'];
if (empty($answer)) {
$randomValue = mt_rand(1, $nbrAnswers);
$answer = $objAnswerTmp->selectAnswer($randomValue);
$calculatedAnswer = Session::read('calculatedAnswerId');
$calculatedAnswer[$questionId] = $randomValue;
Session::write('calculatedAnswerId', $calculatedAnswer);
$_SESSION['calculatedAnswerId'][$questionId] = mt_rand(
1,
$nbrAnswers
);
$answer = $objAnswerTmp->selectAnswer(
$_SESSION['calculatedAnswerId'][$questionId]
);
}
}
@ -684,8 +939,7 @@ class ExerciseLib
$correctAnswerList
);
// get student answer to display it if student go back to
// previous calculated answer question in a test
// get student answer to display it if student go back to previous calculated answer question in a test
if (isset($user_choice[0]['answer'])) {
api_preg_match_all(
'/\[[^]]+\]/',
@ -695,7 +949,9 @@ class ExerciseLib
$studentAnswerListTobecleaned = $studentAnswerList[0];
$studentAnswerList = [];
for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) {
for ($i = 0; $i < count(
$studentAnswerListTobecleaned
); $i++) {
$answerCorrected = $studentAnswerListTobecleaned[$i];
$answerCorrected = api_preg_replace(
'| / <font color="green"><b>.*$|',
@ -722,8 +978,7 @@ class ExerciseLib
}
}
// If display preview of answer in test view for exaemple,
// set the student answer to the correct answers
// If display preview of answer in test view for exemple, set the student answer to the correct answers
if ($debug_mark_answer) {
// contain the rights answers surronded with brackets
$studentAnswerList = $correctAnswerList[0];
@ -742,7 +997,7 @@ class ExerciseLib
' '.$answer.' '
);
if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
$answer = '';
$answer = "";
$i = 0;
foreach ($studentAnswerList as $studentItem) {
// remove surronding brackets
@ -835,8 +1090,8 @@ class ExerciseLib
if (isset($select_items[$lines_count])) {
$s .= '<div class="text-right">
<p class="indent">'.
$select_items[$lines_count]['letter'].'.&nbsp; '.
$select_items[$lines_count]['answer'].'
$select_items[$lines_count]['letter'].'.&nbsp; '.
$select_items[$lines_count]['answer'].'
</p>
</div>';
} else {
@ -854,7 +1109,7 @@ class ExerciseLib
<td colspan="2"></td>
<td valign="top">';
$s .= '<b>'.$select_items[$lines_count]['letter'].'.</b> '.
$select_items[$lines_count]['answer'];
$select_items[$lines_count]['answer'];
$s .= "</td>
</tr>";
$lines_count++;
@ -1074,6 +1329,7 @@ HTML;
UNIQUE_ANSWER_NO_OPTION,
MULTIPLE_ANSWER_TRUE_FALSE,
MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE,
MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY
]
)) {
$s .= '</table>';
@ -1679,10 +1935,9 @@ HOTSPOT;
* @param null $extra_where_conditions
* @param bool $get_count
* @param string $courseCode
* @param bool $showSessionField
* @param bool $showExerciseCategories
* @param array $userExtraFieldsToAdd
* @param bool $useCommaAsDecimalPoint
* @param bool $showSessionField
* @param bool $showExerciseCategories
* @param array $userExtraFieldsToAdd
*
* @return array
*/
@ -1697,8 +1952,7 @@ HOTSPOT;
$courseCode = null,
$showSessionField = false,
$showExerciseCategories = false,
$userExtraFieldsToAdd = [],
$useCommaAsDecimalPoint = false
$userExtraFieldsToAdd = []
) {
//@todo replace all this globals
global $documentPath, $filter;
@ -1711,12 +1965,7 @@ HOTSPOT;
}
$course_id = $courseInfo['real_id'];
$is_allowedToEdit =
api_is_allowed_to_edit(null, true) ||
api_is_allowed_to_edit(true) ||
api_is_drh() ||
api_is_student_boss() ||
api_is_session_admin();
$is_allowedToEdit = api_is_allowed_to_edit(null, true) || api_is_allowed_to_edit(true) || api_is_drh() || api_is_student_boss();
$TBL_USER = Database::get_main_table(TABLE_MAIN_USER);
$TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
$TBL_GROUP_REL_USER = Database::get_course_table(TABLE_GROUP_USER);
@ -1943,7 +2192,9 @@ HOTSPOT;
return $rowx[0];
}
$teacher_list = CourseManager::get_teacher_list_from_course_code($courseCode);
$teacher_list = CourseManager::get_teacher_list_from_course_code(
$courseCode
);
$teacher_id_list = [];
if (!empty($teacher_list)) {
foreach ($teacher_list as $teacher) {
@ -1951,15 +2202,6 @@ HOTSPOT;
}
}
$scoreDisplay = new ScoreDisplay();
$decimalSeparator = '.';
$thousandSeparator = ',';
if ($useCommaAsDecimalPoint) {
$decimalSeparator = ',';
$thousandSeparator = '';
}
$listInfo = [];
// Simple exercises
if (empty($hotpotatoe_where)) {
@ -1977,6 +2219,7 @@ HOTSPOT;
while ($rowx = Database::fetch_array($resx, 'ASSOC')) {
$results[] = $rowx;
}
$group_list = GroupManager::get_group_list(null, $courseInfo);
$clean_group_list = [];
if (!empty($group_list)) {
@ -1989,7 +2232,7 @@ HOTSPOT;
$lp_list = $lp_list_obj->get_flat_list();
$oldIds = array_column($lp_list, 'lp_old_id', 'iid');
if (!empty($results)) {
if (is_array($results)) {
$users_array_id = [];
$from_gradebook = false;
if (isset($_GET['gradebook']) && $_GET['gradebook'] == 'view') {
@ -1997,7 +2240,11 @@ HOTSPOT;
}
$sizeof = count($results);
$user_list_id = [];
$locked = api_resource_is_locked_by_gradebook($exercise_id, LINK_EXERCISE);
$locked = api_resource_is_locked_by_gradebook(
$exercise_id,
LINK_EXERCISE
);
$timeNow = strtotime(api_get_utc_datetime());
// Looping results
for ($i = 0; $i < $sizeof; $i++) {
@ -2079,9 +2326,10 @@ HOTSPOT;
// we filter the results if we have the permission to
$result_disabled = 0;
if (isset($results[$i]['results_disabled'])) {
$result_disabled = (int) $results[$i]['results_disabled'];
$result_disabled = intval(
$results[$i]['results_disabled']
);
}
if ($result_disabled == 0) {
$my_res = $results[$i]['exe_result'];
$my_total = $results[$i]['exe_weighting'];
@ -2093,19 +2341,9 @@ HOTSPOT;
$my_res = 0;
}
$score = self::show_score(
$my_res,
$my_total,
true,
true,
false,
false,
$decimalSeparator,
$thousandSeparator
);
$score = self::show_score($my_res, $my_total);
$actions = '<div class="pull-right">';
if ($is_allowedToEdit) {
if (isset($teacher_id_list)) {
if (in_array(
@ -2190,7 +2428,7 @@ HOTSPOT;
}
// Admin can always delete the attempt
if (($locked == false || (api_is_platform_admin()) && !api_is_student_boss())) {
if (($locked == false || api_is_platform_admin()) && !api_is_student_boss()) {
$ip = Tracking::get_ip_from_user_event(
$results[$i]['exe_user_id'],
api_get_utc_datetime(),
@ -2221,10 +2459,10 @@ HOTSPOT;
$filterByUser = isset($_GET['filter_by_user']) ? (int) $_GET['filter_by_user'] : 0;
$delete_link = '<a href="exercise_report.php?'.api_get_cidreq().'&filter_by_user='.$filterByUser.'&filter='.$filter.'&exerciseId='.$exercise_id.'&delete=delete&did='.$id.'"
onclick="javascript:if(!confirm(\''.sprintf(
get_lang('DeleteAttempt'),
$results[$i]['username'],
$dt
).'\')) return false;">';
get_lang('DeleteAttempt'),
$results[$i]['username'],
$dt
).'\')) return false;">';
$delete_link .=
Display:: return_icon(
'delete.png',
@ -2235,9 +2473,6 @@ HOTSPOT;
if (api_is_drh() && !api_is_platform_admin()) {
$delete_link = null;
}
if (api_is_session_admin()) {
$delete_link = '';
}
if ($revised == 3) {
$delete_link = null;
}
@ -2353,17 +2588,7 @@ HOTSPOT;
}
foreach ($category_list as $categoryId => $result) {
$scoreToDisplay = self::show_score(
$result['score'],
$result['total'],
true,
true,
false,
false,
$decimalSeparator,
$thousandSeparator
);
$scoreToDisplay = self::show_score($result['score'], $result['total']);
$results[$i]['category_'.$categoryId] = $scoreToDisplay;
$results[$i]['category_'.$categoryId.'_score_percentage'] = self::show_score(
$result['score'],
@ -2371,9 +2596,7 @@ HOTSPOT;
true,
true,
true, // $show_only_percentage = false
true, // hide % sign
$decimalSeparator,
$thousandSeparator
true // hide % sign
);
$results[$i]['category_'.$categoryId.'_only_score'] = $result['score'];
$results[$i]['category_'.$categoryId.'_total'] = $result['total'];
@ -2388,23 +2611,10 @@ HOTSPOT;
true,
true,
true,
true,
$decimalSeparator,
$thousandSeparator
);
$results[$i]['only_score'] = $scoreDisplay->format_score(
$my_res,
false,
$decimalSeparator,
$thousandSeparator
);
$results[$i]['total'] = $scoreDisplay->format_score(
$my_total,
false,
$decimalSeparator,
$thousandSeparator
true
);
$results[$i]['only_score'] = $my_res;
$results[$i]['total'] = $my_total;
$results[$i]['lp'] = $lp_name;
$results[$i]['actions'] = $actions;
$listInfo[] = $results[$i];
@ -2478,14 +2688,12 @@ HOTSPOT;
* Converts the score with the exercise_max_note and exercise_min_score
* the platform settings + formats the results using the float_format function.
*
* @param float $score
* @param float $weight
* @param bool $show_percentage show percentage or not
* @param bool $use_platform_settings use or not the platform settings
* @param bool $show_only_percentage
* @param bool $hidePercentageSign hide "%" sign
* @param string $decimalSeparator
* @param string $thousandSeparator
* @param float $score
* @param float $weight
* @param bool $show_percentage show percentage or not
* @param bool $use_platform_settings use or not the platform settings
* @param bool $show_only_percentage
* @param bool $hidePercetangeSign hide "%" sign
*
* @return string an html with the score modified
*/
@ -2495,9 +2703,7 @@ HOTSPOT;
$show_percentage = true,
$use_platform_settings = true,
$show_only_percentage = false,
$hidePercentageSign = false,
$decimalSeparator = '.',
$thousandSeparator = ','
$hidePercetangeSign = false
) {
if (is_null($score) && is_null($weight)) {
return '-';
@ -2519,13 +2725,14 @@ HOTSPOT;
$percentage = (100 * $score) / ($weight != 0 ? $weight : 1);
// Formats values
$percentage = float_format($percentage, 1, $decimalSeparator, $thousandSeparator);
$score = float_format($score, 1, $decimalSeparator, $thousandSeparator);
$weight = float_format($weight, 1, $decimalSeparator, $thousandSeparator);
$percentage = float_format($percentage, 1);
$score = float_format($score, 1);
$weight = float_format($weight, 1);
$html = '';
if ($show_percentage) {
$percentageSign = '%';
if ($hidePercentageSign) {
if ($hidePercetangeSign) {
$percentageSign = '';
}
$html = $percentage."$percentageSign ($score / $weight)";
@ -2555,7 +2762,9 @@ HOTSPOT;
*/
public static function getModelStyle($model, $percentage)
{
//$modelWithStyle = get_lang($model['name']);
$modelWithStyle = '<span class="'.$model['css_class'].'"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>';
//$modelWithStyle .= $percentage;
return $modelWithStyle;
}
@ -3315,7 +3524,10 @@ EOT;
$avg_score = 0;
if (!empty($user_results)) {
foreach ($user_results as $result) {
if (!empty($result['exe_weighting']) && intval($result['exe_weighting']) != 0) {
if (!empty($result['exe_weighting']) && intval(
$result['exe_weighting']
) != 0
) {
$score = $result['exe_result'] / $result['exe_weighting'];
$avg_score += $score;
}
@ -3510,8 +3722,7 @@ EOT;
*
* @param int $question_id
* @param int $exercise_id
*
* @return array
* @return int
*/
public static function getNumberStudentsFillBlanksAnswerCount(
$question_id,
@ -3535,6 +3746,7 @@ EOT;
);
$arrayCount = [];
foreach ($listFillTheBlankResult as $resultCount) {
foreach ($resultCount as $index => $count) {
//this is only for declare the array index per answer
@ -3997,6 +4209,41 @@ EOT;
return $return;
}
/**
* @param string $in_name is the name and the id of the <select>
* @param string $in_default default value for option
* @param string $in_onchange
* @return string the html code of the <select>
*/
public static function displayGroupMenu($in_name, $in_default, $in_onchange = "")
{
// check the default value of option
$tabSelected = [$in_default => " selected='selected' "];
$res = "";
$res .= "<select name='$in_name' id='$in_name' onchange='".$in_onchange."' >";
$res .= "<option value='-1'".$tabSelected["-1"].">-- ".get_lang(
'AllGroups'
)." --</option>";
$res .= "<option value='0'".$tabSelected["0"].">- ".get_lang(
'NotInAGroup'
)." -</option>";
$tabGroups = GroupManager::get_group_list();
$currentCatId = 0;
for ($i = 0; $i < count($tabGroups); $i++) {
$tabCategory = GroupManager::get_category_from_group(
$tabGroups[$i]['iid']
);
if ($tabCategory["id"] != $currentCatId) {
$res .= "<option value='-1' disabled='disabled'>".$tabCategory["title"]."</option>";
$currentCatId = $tabCategory["id"];
}
$res .= "<option ".$tabSelected[$tabGroups[$i]["id"]]."style='margin-left:40px' value='".$tabGroups[$i]["id"]."'>".
$tabGroups[$i]["name"]."</option>";
}
$res .= "</select>";
return $res;
}
/**
* @param int $exe_id
*/
@ -4323,17 +4570,35 @@ EOT;
} // end foreach() block that loops over all questions
}
$total_score_text = null;
$totalScoreText = null;
if ($show_results || $show_only_score) {
$total_score_text .= '<div class="question_row_score">';
$total_score_text .= self::getTotalScoreRibbon(
$objExercise,
$total_score,
$total_weight,
true,
$countPendingQuestions
);
$total_score_text .= '</div>';
if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
echo "<h1 style='text-align : center; margin : 20px 0;'>Vos Résultats</h1><br>";
}
$totalScoreText .= '<div class="question_row_score">';
if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){
$totalScoreText .= self::getQuestionRibbonDiag($objExercise,
$total_score,
$total_weight,
true
);
} else {
$totalScoreText .= self::getTotalScoreRibbon(
$objExercise,
$total_score,
$total_weight,
true,
$countPendingQuestions
);
}
$totalScoreText .= '</div>';
}
if($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){
$chartMultiAnswer = MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults(
$exeId,
$objExercise);
echo $chartMultiAnswer;
}
if (!empty($category_list) && ($show_results || $show_only_score)) {
@ -4349,8 +4614,7 @@ EOT;
}
if ($show_all_but_expected_answer) {
$exercise_content .= "<div class='normal-message'>".
get_lang('ExerciseWithFeedbackWithoutCorrectionComment')."</div>";
$exercise_content .= "<div class='normal-message'>".get_lang('ExerciseWithFeedbackWithoutCorrectionComment')."</div>";
}
// Remove audio auto play from questions on results page - refs BT#7939
@ -4360,7 +4624,7 @@ EOT;
$exercise_content
);
echo $total_score_text;
echo $totalScoreText;
// Ofaj change BT#11784
if (!empty($objExercise->description)) {
@ -4370,7 +4634,7 @@ EOT;
echo $exercise_content;
if (!$show_only_score) {
echo $total_score_text;
echo $totalScoreText;
}
if (!empty($remainingMessage)) {
@ -4418,6 +4682,57 @@ EOT;
}
}
/**
* @param Exercise $objExercise
* @param float $score
* @param float $weight
* @param bool $checkPassPercentage
* @return string
*/
public static function getQuestionRibbonDiag($objExercise, $score, $weight, $checkPassPercentage = false) {
$displayChartDegree = true;
$ribbon = $displayChartDegree? '<div class="ribbon">' : '';
if ($checkPassPercentage) {
$isSuccess = self::isSuccessExerciseResult(
$score, $weight, $objExercise->selectPassPercentage()
);
// Color the final test score if pass_percentage activated
$ribbonTotalSuccessOrError = "";
if (self::isPassPercentageEnabled($objExercise->selectPassPercentage())) {
if ($isSuccess) {
$ribbonTotalSuccessOrError = ' ribbon-total-success';
} else {
$ribbonTotalSuccessOrError = ' ribbon-total-error';
}
}
$ribbon .= $displayChartDegree? '<div class="rib rib-total ' . $ribbonTotalSuccessOrError . '">' : '';
} else {
$ribbon .= $displayChartDegree? '<div class="rib rib-total">' : '';
}
if ($displayChartDegree){
$ribbon .= '<h3>' . get_lang('YourTotalScore') . ":&nbsp;";
$ribbon .= self::show_score($score, $weight, false, true);
$ribbon .= '</h3>';
$ribbon .= '</div>';
}
if ($checkPassPercentage) {
$ribbon .= self::showSuccessMessage(
$score, $weight, $objExercise->selectPassPercentage()
);
}
$ribbon .= $displayChartDegree? '</div>' : '';
return $ribbon;
}
/**
* @param Exercise $objExercise
* @param float $score

@ -496,6 +496,105 @@ class ExerciseShowFunctions
echo '</tr>';
}
/**
* Display the answers to a multiple choice question
*
* @param int $feedbackType
* @param int $studentChoice
* @param int $studentChoiceDegree
* @param string $answer
* @param string $answerComment
* @param int $answerCorrect
* @param int $id
* @param int $questionId
* @param int $answerNumber
* @param boolean $inResultsDisabled
* @return void
*/
static function displayMultipleAnswerTrueFalseDegreeCertainty(
$feedbackType, $studentChoice, $studentChoiceDegree, $answer, $answerComment, $answerCorrect, $id, $questionId, $answerNumber, $inResultsDisabled
) {
$hideExpectedAnswer = false;
if ($feedbackType == 0 && $inResultsDisabled == 2) {
$hideExpectedAnswer = true;
}
?>
<tr>
<td width="5%">
<?php
$question = new MultipleAnswerTrueFalseDegreeCertainty();
$courseId = api_get_course_int_id();
$newOptions = Question::readQuestionOption($questionId, $courseId);
//Your choice
if (isset($newOptions[$studentChoice])) {
echo get_lang($newOptions[$studentChoice]['name']);
} else {
echo '-';
}
?>
</td>
<td width="5%">
<?php
//Expected choice
if (!$hideExpectedAnswer) {
if (isset($newOptions[$answerCorrect])) {
echo get_lang($newOptions[$answerCorrect]['name']);
} else {
echo '-';
}
} else {
echo '-';
}
?>
</td>
<td width="25%">
<?php echo $answer; ?>
</td>
<td width="5%" style="text-align:center;">
<?php
echo $newOptions[$studentChoiceDegree]['name'];
?>
</td>
<!-- color by certainty -->
<?php
$degreCertitudeColor = $question->getColorResponse($studentChoice,
$answerCorrect,
$newOptions[$studentChoiceDegree]['position']
);
if($degreCertitudeColor == "#088A08" || $degreCertitudeColor == "#FE2E2E"){
$color = "#FFFFFF";
} else {
$color = "#000000";
}
$codeResponse = $question->getCodeResponse($studentChoice,
$answerCorrect,
$newOptions[$studentChoiceDegree]['position']
);
?>
<td width="10%">
<div style="text-align:center;color: <?php echo $color; ?>; border:1px #D6D4D4 solid;background-color: <?php echo $degreCertitudeColor; ?>; line-height:30px;height:30px;width: 100%;margin:auto;"><?php echo nl2br($codeResponse); ?></div>
</td>
<?php if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
<td width="20%">
<?php
$color = "black";
if (isset($newOptions[$studentChoice])) {
echo '<span style="font-weight: bold; color: ' . $color . ';">' . nl2br($answerComment) . '</span>';
}
?>
</td>
<?php } else { ?>
<td>&nbsp;</td>
<?php } ?>
</tr>
<?php
}
/**
* Display the answers to a multiple choice question.
*

@ -239,7 +239,7 @@ $WithoutCategory = "Sans catégorie";
$IncorrectScore = "Score réponse incorrecte";
$CorrectScore = "Score réponse correcte";
$UseCustomScoreForAllQuestions = "Utiliser le score sur mesure pour toutes les questions";
$YouShouldAddItemsBeforeAttachAudio = "
$YouShouldAddItemsBeforeAttachAudio = "
Vous devez ajouter des étapes à votre parcours avant de pouvoir leur affecter des fichiers audio";
$InactiveDays = "Jours inactifs";
$FollowedHumanResources = "DRH suivis";
@ -326,23 +326,23 @@ $DeleteUsersNotInList = "Désinscrite les apprenants qui ne sont pas dans la lis
$IfSessionExistsUpdate = "Si une session existe, la mettre à jour";
$CreatedByXYOnZ = "Créé(e) par <a href=\"%s\">%s</a>, le %s";
$LoginWithExternalAccount = "S'authentifier avec un compte extérieur à l'établissement";
$ImportAikenQuizExplanationExample = "Ceci est le texte de la question 1
A. Réponse 1
B. Réponse 2
C. Réponse 3
ANSWER: B
Ceci est le texte de la question 2
A. Réponse 1
B. Réponse 2
C. Réponse 3
D. Réponse 4
ANSWER: D
$ImportAikenQuizExplanationExample = "Ceci est le texte de la question 1
A. Réponse 1
B. Réponse 2
C. Réponse 3
ANSWER: B
Ceci est le texte de la question 2
A. Réponse 1
B. Réponse 2
C. Réponse 3
D. Réponse 4
ANSWER: D
ANSWER_EXPLANATION: C'est un commentaire facultatif de retour qui apparaîtra à côté de la bonne réponse.";
$ImportAikenQuizExplanation = "Le format Aiken est un fichier (.txt) avec un texte simple, avec plusieurs blocs de questions, chacune séparée par une ligne blanche. La première ligne est la question, les lignes de réponse sont préfixés par une lettre et un point, et la bonne réponse vient avec le préfixe 'ANSWER'.
$ImportAikenQuizExplanation = "Le format Aiken est un fichier (.txt) avec un texte simple, avec plusieurs blocs de questions, chacune séparée par une ligne blanche. La première ligne est la question, les lignes de réponse sont préfixés par une lettre et un point, et la bonne réponse vient avec le préfixe 'ANSWER'.
Voir l'exemple ci-dessous.";
$ExerciseAikenErrorNoAnswerOptionGiven = "Le fichier importé comporte au moins une question sans réponse (ou les réponses ne comprennent pas la lettre de préfixe requis). Assurez-vous que chaque question a au moins une réponse et qu'elle est précédée par une lettre et un point ou une parenthèse, comme ceci:
$ExerciseAikenErrorNoAnswerOptionGiven = "Le fichier importé comporte au moins une question sans réponse (ou les réponses ne comprennent pas la lettre de préfixe requis). Assurez-vous que chaque question a au moins une réponse et qu'elle est précédée par une lettre et un point ou une parenthèse, comme ceci:
A. Réponse 1";
$ExerciseAikenErrorNoCorrectAnswerDefined = "Le fichier importé comporte au moins une question sans réponse correcte définie. Assurez-vous que toutes les questions comprennent la réponse: [Lettre] ligne.";
$SearchCourseBySession = "Recherche de cours par session";
@ -837,10 +837,10 @@ $AllowVisitors = "Permettre des visiteurs externes";
$EnableIframeInclusionComment = "Autoriser les balises iframe dans l'éditeur HTML améliore l'édition de documents mais peut représenter un risque pour la sécurité.";
$AddedToLPCannotBeAccessed = "Cet exercice fait partie d'un parcours d'apprentissage, il n'est donc pas accessible par les étudiants depuis cette page. Si vous voulez rendre cet exercice disponible depuis l'outil exercice, vous devez en faire une copie en utilisant l'icône \"Copie\"";
$EnableIframeInclusionTitle = "Autoriser les balises iframe dans l'éditeur HTML.";
$MailTemplateRegistrationMessage = "Cher(ère) ((firstname)) ((lastname)), Vous êtes inscrit(e) sur
((sitename) avec les paramètres suivants: Nom d'utilisateur :
((username)) Mot de passe : ((password)) L'adresse de ((sitename)) est :
((url)) En cas de problème, n'hésitez pas à prendre contact avec nous
$MailTemplateRegistrationMessage = "Cher(ère) ((firstname)) ((lastname)), Vous êtes inscrit(e) sur
((sitename) avec les paramètres suivants: Nom d'utilisateur :
((username)) Mot de passe : ((password)) L'adresse de ((sitename)) est :
((url)) En cas de problème, n'hésitez pas à prendre contact avec nous
Cordialement, le responsable ((admin_name)) ((admin_surname)).";
$Explanation = "Une fois que vous aurez cliqué sur OK, un cours contenant Tests, Documents, Parcours d'Apprentissage SCORM... sera créé. Grâce à votre identifiant de responsable du cours vous pourrez en modifier le contenu";
$CodeTaken = "Ce code est déjà pris.<br />Utilisez le bouton de retour en arrière de votre navigateur et recommencez";
@ -2633,14 +2633,14 @@ $NoPosts = "Aucune publication";
$WithoutAchievedSkills = "Aucune compétence acquise";
$TypeMessage = "Veuillez introduire votre message !";
$ConfirmReset = "Êtes-vous sûr de vouloir supprimer tous les messages ?";
$MailCronCourseExpirationReminderBody = "Cher/Chère %s,
Nous avons remarqué que vous n'avez pas terminé le cours %s alors que sa date de fin a été établie au %s, vous laissant %s jour(s) pour le terminer. Nous vous rappelons que vous ne disposez de la possibilité de suivre ce cours qu'une fois par an. Nous vous invitons donc avec insistance à le compléter dans le délai qu'il vous reste. Vous pouvez retrouver le cours en vous connectant à la plate-forme à cette adresse: %s
--
Cordialement,
$MailCronCourseExpirationReminderBody = "Cher/Chère %s,
Nous avons remarqué que vous n'avez pas terminé le cours %s alors que sa date de fin a été établie au %s, vous laissant %s jour(s) pour le terminer. Nous vous rappelons que vous ne disposez de la possibilité de suivre ce cours qu'une fois par an. Nous vous invitons donc avec insistance à le compléter dans le délai qu'il vous reste. Vous pouvez retrouver le cours en vous connectant à la plate-forme à cette adresse: %s
--
Cordialement,
L'équipe de support de %s";
$MailCronCourseExpirationReminderSubject = "Urgent: Rappel d'expiration prochaine du cours %s";
$ExerciseAndLearningPath = "Exercices et parcours";
@ -5547,7 +5547,7 @@ $AssignCoursesToHumanResourcesManager = "Assigner des cours au directeur RH";
$TimezoneValueTitle = "Fuseau horaire";
$TimezoneValueComment = "Le fuseau horaire de ce portail devrait être réglé sur celui du siège de l'organisation. Si vous ne configurez pas de fuseau horaire, celui du serveur sera utilisé. Si vous en configurez un, toutes les heures de cette plateforme seront affichées sur base de ce fuseau. Ce paramètre a une priorité inférieure à celui de l'utilisateur, s'il en a activé et sélectionné personnellement dans son profil étendu.";
$UseUsersTimezoneTitle = "Utiliser les fuseaux horaires utilisateurs";
$UseUsersTimezoneComment = "Activer la possibilité pour les utilisateurs de sélectionner leur fuseau horaire. Le champ de fuseau horaire doit être rendu visible et modifiable dans les options de profiling du panneau d'administration avant que les utilisateurs ne puissent choisir leur propre fuseau.
$UseUsersTimezoneComment = "Activer la possibilité pour les utilisateurs de sélectionner leur fuseau horaire. Le champ de fuseau horaire doit être rendu visible et modifiable dans les options de profiling du panneau d'administration avant que les utilisateurs ne puissent choisir leur propre fuseau.
Une fois configuré, les utilisateurs pourront voir toutes les heures du portail (heure de remise des travaux, événements, etc) converties dans leur fuseau horaire personnel.";
$FieldTypeTimezone = "Fuseau horaire";
$Timezone = "Fuseaux horaires";
@ -5821,8 +5821,8 @@ $Item = "Élément";
$ConfigureDashboardPlugin = "Configurer le plugin de tableau de bord";
$EditBlocks = "Éditer les blocs";
$Never = "Jamais";
$YourAccountIsActiveYouCanLoginAndCheckYourCourses = "Cher utilisateur,
$YourAccountIsActiveYouCanLoginAndCheckYourCourses = "Cher utilisateur,
Votre compte a été activé. Vous pouvez à présent vous connecter et consulter vos cours.";
$SessionFields = "Champs de session";
$CopyLabelSuffix = "Copie";
@ -5884,7 +5884,7 @@ $CourseSettingsRegisterDirectLink = "Si votre cours est public ou ouvert, utilis
$DirectLink = "Lien direct";
$here = "ici";
$GoAheadAndBrowseOurCourseCatalogXOnceRegisteredYouWillSeeTheCourseHereX = "Révisez notre catalogue de cours %s pour vous inscrire à votre cours préféré. Une fois inscrit(e), votre cours apparaîtra %s, à la place de ce message.";
$HelloXAsYouCanSeeYourCourseListIsEmpty = "Bonjour %s, nous vous souhaitons la bienvenue,<br />
$HelloXAsYouCanSeeYourCourseListIsEmpty = "Bonjour %s, nous vous souhaitons la bienvenue,<br />
Comme vous pouvez le voir, votre liste de cours est vide. C'est parce que vous ne vous êtes pas encore inscrit à un cours!";
$UnsubscribeUsersAlreadyAddedInCourse = "Désinscrire les utilisateurs actuellement inscrits";
$ImportUsers = "Importer des utilisateurs";
@ -5966,11 +5966,11 @@ $ContactInformationHasBeenSent = "L'information de contact a été envoyée. Mer
$EditExtraFieldOptions = "Modifier les options de champs";
$ExerciseDescriptionLabel = "Description";
$UserInactivedSinceX = "Utilisateur inactif depuis %s";
$ContactInformationDescription = "Cher utilisateur,<br />
<br />
Vous êtes sur le point de commencer à utiliser l'une des meilleures plateformes e-learning de logiciel libre du marché. Comme beaucoup d'autres projets de logiciel libre, celui-ci est supporté par une grande communauté d'étudiants, d'enseignants, de développeurs et de créateurs de contenu qui aimeraient pouvoir promouvoir le projet dans les meilleures conditions.<br /><br />
Au travers d'une meilleure connaissance de notre public et de l'un de nos plus importants utilisateurs, vous, qui gèrerez ce système e-learning, nous pourrons nous assurer de faire savoir au plus grand nombre que notre logiciel est utilisé, et nous pourrons vous informer directement sur les événements importants à vos yeux.<br /><br />
En complétant ce formulaire, vous acceptez que l'Association Chamilo ou ses membres puissent vous envoyer des informations par courriel au sujet d'événements importants ou de mises à jours du logiciel ou de la communauté. Ceci aidera la communauté à croître comme une entité organisée au sein de laquelle l'information se propage, au travers d'un respect permanent de votre temps et de votre vie privée.<br /><br />
$ContactInformationDescription = "Cher utilisateur,<br />
<br />
Vous êtes sur le point de commencer à utiliser l'une des meilleures plateformes e-learning de logiciel libre du marché. Comme beaucoup d'autres projets de logiciel libre, celui-ci est supporté par une grande communauté d'étudiants, d'enseignants, de développeurs et de créateurs de contenu qui aimeraient pouvoir promouvoir le projet dans les meilleures conditions.<br /><br />
Au travers d'une meilleure connaissance de notre public et de l'un de nos plus importants utilisateurs, vous, qui gèrerez ce système e-learning, nous pourrons nous assurer de faire savoir au plus grand nombre que notre logiciel est utilisé, et nous pourrons vous informer directement sur les événements importants à vos yeux.<br /><br />
En complétant ce formulaire, vous acceptez que l'Association Chamilo ou ses membres puissent vous envoyer des informations par courriel au sujet d'événements importants ou de mises à jours du logiciel ou de la communauté. Ceci aidera la communauté à croître comme une entité organisée au sein de laquelle l'information se propage, au travers d'un respect permanent de votre temps et de votre vie privée.<br /><br />
Veuillez prendre en considération que vous n'êtes <b>pas obligé</b> de compléter ce formulaire. Si vous désirez rester anonyme, nous perdrons la possibilité de vous offrir les privilèges d'être un administrateur de portail enregistré, mais nous respecterons votre décision. Laissez simplement ce formulaire vide et cliquez sur \"Suivant\". De même, une fois l'envoi de l'information du formulaire ci-dessous confirmé, vous devrez cliquer sur \"Suivant\".";
$CompanyActivity = "Activité de votre entreprise";
$PleaseAllowUsALittleTimeToSubscribeYouToOneOfOurCourses = "Merci de nous donner un moment pour vous inscrire à l'un de nos cours. Si vous pensez avoir été oublié, merci de contacter les administrateurs du site. Vous pouvez généralement trouver leurs informations de contact dans le pied de page.";
@ -6127,7 +6127,7 @@ $SSOServerUnAuthURIComment = "L'adresse de la page qui se charge de la déconnex
$SSOServerProtocolTitle = "Protocole du serveur Single Sign On";
$SSOServerProtocolComment = "Le protocole à préfixer au domaine du serveur Single Sign On (nous recommandons l'usage de https:// si votre serveur le permet, car tout protocole non sécurisé engendre des risques au niveau du mécanisme d'authentification).";
$EnabledWirisTitle = "Éditeur mathématique WIRIS";
$EnabledWirisComment = "Activer l'éditeur mathématique WIRIS. En installant ce plugin, vous obtenez l'éditeur WIRIS et WIRIS CAS.<br/>Cette activation n'est totalement réalisée que si le <a href=\"http://www.wiris.com/es/plugins3/ckeditor/download\">plugin PHP pour CKeditor WIRIS</a> a été préalablement téléchargé et décompressé dans le répertoire de Chamilo main/inc/lib/javascript/ckeditor/plugins/.<br/>
$EnabledWirisComment = "Activer l'éditeur mathématique WIRIS. En installant ce plugin, vous obtenez l'éditeur WIRIS et WIRIS CAS.<br/>Cette activation n'est totalement réalisée que si le <a href=\"http://www.wiris.com/es/plugins3/ckeditor/download\">plugin PHP pour CKeditor WIRIS</a> a été préalablement téléchargé et décompressé dans le répertoire de Chamilo main/inc/lib/javascript/ckeditor/plugins/.<br/>
Cela est nécessaire car Wiris est un logiciel propriétaire et ses services sont de nature <a href=\"http://www.wiris.com/store/who-pays\">commerciale</a>. Pour faire des ajustements pour le plug-in, éditer le fichier configuration.ini ou remplacer son contenu par le fichier configuration.ini.default de Chamilo.";
$FileSavedAs = "Le fichier a été enregistré sous";
$FileExportAs = "Le fichier a été exporté sous";
@ -6152,9 +6152,9 @@ $AverageScore = "Score moyen";
$LastConnexionDate = "Date de dernière connexion";
$ToolVideoconference = "Vidéoconférence";
$BigBlueButtonEnableTitle = "Outil de vidéoconférence BigBlueButton";
$BigBlueButtonEnableComment = "Choisissez si vous désirez activer l'outil de vidéoconférence BigBlueButton. Une fois activé, il apparaît comme un outil de cours additionnel sur toutes les pages d'accueil de cours, et les enseignants peuvent lancer une conférence à tout moment. Les étudiants ne peuvent pas lancer de conférence, seulement en rejoindre.
Si vous n'avez pas de serveur BigBlueButton fonctionnel, veuillez <a target=\"_blank\" href=\"http://bigbluebutton.org/\">en installer un</a> ou vous adresser aux <a target=\"_blank\" href=\"http://www.chamilo.org/en/providers\">fournisseurs officiels de Chamilo</a> pour pouvoir bénéficier de cette fonctionnalité.
BigBlueButton est un logiciel libre et gratuit. Son installation requiert des compétences techniques particulières, ce qui demande un travail considérable et peut résulter coûteux si vous ne disposez pas desdites compétences.
$BigBlueButtonEnableComment = "Choisissez si vous désirez activer l'outil de vidéoconférence BigBlueButton. Une fois activé, il apparaît comme un outil de cours additionnel sur toutes les pages d'accueil de cours, et les enseignants peuvent lancer une conférence à tout moment. Les étudiants ne peuvent pas lancer de conférence, seulement en rejoindre.
Si vous n'avez pas de serveur BigBlueButton fonctionnel, veuillez <a target=\"_blank\" href=\"http://bigbluebutton.org/\">en installer un</a> ou vous adresser aux <a target=\"_blank\" href=\"http://www.chamilo.org/en/providers\">fournisseurs officiels de Chamilo</a> pour pouvoir bénéficier de cette fonctionnalité.
BigBlueButton est un logiciel libre et gratuit. Son installation requiert des compétences techniques particulières, ce qui demande un travail considérable et peut résulter coûteux si vous ne disposez pas desdites compétences.
Dans la logique du développement durable de notre projet, nous vous offrons la possibilité d'installer vous-même la solution ou de vous faire aider par des professionnels à l'expérience démontrée.";
$BigBlueButtonHostTitle = "Adresse du serveur BigBlueButton";
$BigBlueButtonHostComment = "Veuillez indiquer l'adresse du serveur BigBlueButton. Ceci peut être <i>localhost</i>, une adresse IP (par exemple <i>192.168.13.54</i> ou un nom de domaine (par exemple <i>my.video.com</i>).";
@ -6233,6 +6233,7 @@ $DisableLPAutoLaunch = "Désactiver lancement automatique du parcours";
$TheLPAutoLaunchSettingIsONStudentsWillBeRedirectToAnSpecificLP = "Le paramètre d'auto-démarrage des parcours d'apprentissage est activé. Lorsque les apprenants entreront dans cet espace de cours, ils seront automatiquement redirigés vers le parcours d'apprentissage sélectionné pour l'auto-démarrage.";
$UniqueAnswerNoOption = "Rép. unique avec ne-sais-pas";
$MultipleAnswerTrueFalse = "Rép. multiples vrai/faux/ne-sais-pas";
$MultipleAnswerTrueFalseDegreeCertainty = "Rép. multiples vrai/faux/degré de certitude";
$MultipleAnswerCombinationTrueFalse = "C. exacte vrai/faux/ne-sais-pas";
$DontKnow = "Ne sais pas";
$ExamNotAvailableAtThisTime = "Examen non disponible pour l'instant";
@ -6294,6 +6295,32 @@ $LatestAttempt = "Dernière tentative";
$PDFWaterMarkHeader = "En-tête en filigrane (exports PDF)";
$False = "Faux";
$DoubtScore = "Ne sais pas";
// remplacer texte "Ne sais pas" par "Degré de certitude" pour MultipleAnswerTrueFalse
$YourDegreeOfCertainty = "Votre degré de certitude";
$DegreeOfCertainty = "Degré de certitude que la réponse soit jugée correcte";
// explication des degré de certitude du tableau d'exercice
$Ignorance = "J’ignore la bonne réponse et j’ai choisi au hasard";
$VeryUnsure = "Je suis très peu sûr";
$Unsure = "Je suis peu sûr";
$PrettySur = "Je suis assez sûr";
$Sur = "Je suis quasiment sûr";
$VerySur = "Je suis tout à fait sûr";
// description des codes couleur
$langVeryUnsure = "Erreur dangereuse";
$langExplainVeryUnsure = " votre réponse a été incorrecte et vous étiez pourtant sûr à 80% ou plus";
$langUnsure = "Erreur présumée";
$langExplainUnsure = "votre réponse a été incorrecte, mais vous en doutiez (certitude 60% ou 70 %)";
$langIgnorance = "Ignorance déclarée";
$langExplainIgnorance = " vous ne connnaissiez pas la réponse - dégré de certitude 50%";
$langPrettySur = "Savoir fragile";
$langExplainPrettySur = "votre réponse a été correcte mais vous etiez peu sûr (certitude 60% ou 70%)";
$langVerySure = "Savoir certain";
$langExplainVerySure = "votre réponse a été correcte et vous etiez sûr à 80% ou plus - <b>félicitation</b>";
$langAnswers = "Réponses";
// description réponse sur les histogrammes
$langCorrectsAnswers = "Réponses correctes";
$langWrongsAnswers = "Réponses incorrectes";
$langIgnoranceAnswers = "Ignorance";
$RegistrationByUsersGroups = "Inscription par groupes d'utilisateurs";
$ContactInformationHasNotBeenSent = "Vos détails de contact n'ont pas pu être envoyés. C'est probablement dû à un problème de réseau. Veuillez essayer à nouveau dans quelques secondes. Si le problème persiste, ignorez simplement ce processus d'inscription et cliquez sur l'autre bouton pour passer à l'étape suivante.";
$FillCourses = "Générer des cours";
@ -6644,7 +6671,7 @@ $DisableEndDate = "Désactiver date de fin";
$ForumCategories = "Catégories de forums";
$Copy = "Copie";
$ArchiveDirCleanup = "Vidange du cache et des fichiers temporaires";
$ArchiveDirCleanupDescr = "Chamilo garde une copie de la plupart des fichiers temporaires qu'il génère (pour les exports, copies et sauvegardes diverses) dans son répertoire app/cache/. Après un certain temps, ces fichiers peuvent s'accumuler et occuper un espace disque assez important et sans intérêt particulier. Cliquez sur le bouton ci-dessous pour vider ce répertoire immédiatement. Idéalement, cette opération devrait être exécutée automatiquement sur base régulière (cron), mais si cela représente une difficulté importante dans votre contexte, vous pouvez visiter cette page de temps en temps pour éliminer tous les fichiers temporaires du répertoire.
$ArchiveDirCleanupDescr = "Chamilo garde une copie de la plupart des fichiers temporaires qu'il génère (pour les exports, copies et sauvegardes diverses) dans son répertoire app/cache/. Après un certain temps, ces fichiers peuvent s'accumuler et occuper un espace disque assez important et sans intérêt particulier. Cliquez sur le bouton ci-dessous pour vider ce répertoire immédiatement. Idéalement, cette opération devrait être exécutée automatiquement sur base régulière (cron), mais si cela représente une difficulté importante dans votre contexte, vous pouvez visiter cette page de temps en temps pour éliminer tous les fichiers temporaires du répertoire.
Cette fonctionnalité nettoie également le cache des thèmes graphiques.";
$ArchiveDirCleanupProceedButton = "Vidanger";
$ArchiveDirCleanupSucceeded = "Le répertoire app/cache/ a été vidangé.";
@ -6998,10 +7025,10 @@ $ShibbolethMainActivateTitle = "<h3>Configuration de l'authentification Shibbole
$ShibbolethMainActivateComment = "<p>Vous devez, en premier lieu, configurer Shibboleth pour votre serveur web. Pour le configurer pour Chamilo.</p><h5>éditez le fichier main/auth/shibboleth/config/aai.class.php</h5><p>Modifiez les valeurs de l'objet &#36;result avec les nom des attributs retourné par votre serveur Shibboleth.</p>Les valeurs à modifier sont<ul><li>&#36;result-&gt;unique_id = 'mail';</li><li>&#36;result-&gt;firstname = 'cn';</li><li>&#36;result-&gt;lastname = 'uid';</li><li>&#36;result-&gt;email = 'mail';</li><li>&#36;result-&gt;language = '-';</li><li>&#36;result-&gt;gender = '-';</li><li>&#36;result-&gt;address = '-';</li><li>&#36;result-&gt;staff_category = '-';</li><li>&#36;result-&gt;home_organization_type = '-'; </li><li>&#36;result-&gt;home_organization = '-';</li><li>&#36;result-&gt;affiliation = '-';</li><li>&#36;result-&gt;persistent_id = '-';</li><li>...</li></ul><br/>Vous trouverez dans les <a href='settings.php?category=Shibboleth'>Plugin</a> un bouton 'Login Shibboleth', paramétrable, qui s'ajoutera sur la page d'accueil de votre campus Chamilo.";
$LdapDescriptionTitle = "Identification LDAP";
$FacebookMainActivateTitle = "<h3>Configuration de l'authentification via Facebook</h3>";
$FacebookMainActivateComment = "<p><h5>Créez votre application Facebook</h5>Vous devez, d'abord, créer une application Facebook (cf. <a href='https://developers.facebook.com/apps'>https://developers.facebook.com/apps</a>) avec votre compte Facebook.<br/>
<h5>Éditez le fichier app/config/configuration.php</h5>Et décommentez la ligne &#36;_configuration['facebook_auth'] = 1;<br/>
<h5>Éditez le fichier app/config/auth.conf.php<br/></h5>Entrez les valeurs 'appId' et 'secret', fournies par Facebook, pour la variable &#36;facebook_config.<br/>
<h5>Éditez le fichier main/inc/conf/auth.conf.php</h5>Et décommentez les lignes &#36;facebook_config<br/>
$FacebookMainActivateComment = "<p><h5>Créez votre application Facebook</h5>Vous devez, d'abord, créer une application Facebook (cf. <a href='https://developers.facebook.com/apps'>https://developers.facebook.com/apps</a>) avec votre compte Facebook.<br/>
<h5>Éditez le fichier app/config/configuration.php</h5>Et décommentez la ligne &#36;_configuration['facebook_auth'] = 1;<br/>
<h5>Éditez le fichier app/config/auth.conf.php<br/></h5>Entrez les valeurs 'appId' et 'secret', fournies par Facebook, pour la variable &#36;facebook_config.<br/>
<h5>Éditez le fichier main/inc/conf/auth.conf.php</h5>Et décommentez les lignes &#36;facebook_config<br/>
<h5>Activez le plugin Facebook de Chamilo<br/></h5>Et placez-le dans la région login_top ou login_bottom.<br/>Vous pouvez changer l'image de connexion dans les options de configuration du plugin.</p>";
$AnnouncementForGroup = "Annonce pour un groupe";
$AllGroups = "Tous les groupes";
@ -7435,7 +7462,7 @@ $CronRemindCourseExpirationFrequencyComment = "Nombre de jours avant la fin du c
$CronCourseFinishedActivateText = "Cron de fin du cours";
$CronCourseFinishedActivateComment = "Activez pour envoyer un courriel lorsque le cours est terminé";
$MailCronCourseFinishedSubject = "Fin du cours: %s";
$MailCronCourseFinishedBody = "Cher/Chère %s,<br/>Merci d'avoir participé au cours %s. Nous espérons que vous avez acquis de nouvelles connaissances et que vous avez pleinement profité du cours. Vous pouvez réviser votre progrès et votre développement personnel au sein du cours dans la section Mon Suivi.<br/>Cordialement,<br/>
$MailCronCourseFinishedBody = "Cher/Chère %s,<br/>Merci d'avoir participé au cours %s. Nous espérons que vous avez acquis de nouvelles connaissances et que vous avez pleinement profité du cours. Vous pouvez réviser votre progrès et votre développement personnel au sein du cours dans la section Mon Suivi.<br/>Cordialement,<br/>
%s";
$GenerateDefaultContent = "Générer du contenu par défaut";
$ThanksForYourSubscription = "Merci pour votre inscription";
@ -7817,7 +7844,7 @@ $TooManyRepetitions = "Trop de répétitions";
$YourPasswordContainsSequences = "Votre mot de passe contient des séquences";
$PasswordVeryWeak = "Très faible";
$UserXHasBeenAssignedToBoss = "L'apprenant %s vous a été assigné";
$UserXHasBeenAssignedToBossWithUrlX = "Vous avez été assigné comme tuteur pour l'apprenant %s.<br/>
$UserXHasBeenAssignedToBossWithUrlX = "Vous avez été assigné comme tuteur pour l'apprenant %s.<br/>
Vous pouvez accéder à sa fiche ici: %s";
$ShortName = "Nom court";
$Portal = "Portail";
@ -7973,13 +8000,13 @@ $AddHrmToUser = "Ajouter Directeur des Ressources Humaines";
$HrmAssignedUsersCourseList = "Liste des cours des utilisateurs assignés au directeur des ressources humaines";
$GoToSurvey = "Aller à l'enquête";
$NotificationCertificateSubject = "Avis d'obtention de certificat";
$NotificationCertificateTemplate = "Cher/Chère ((user_first_name)), vous avez terminé ((course_title)). Votre note finale est de ((score)). Merci de laisser passer quelques jours avant l'apparition de le visualiser sur notre système. Nous espérons que vous en ayez pleinement profité et que nous vous reverrons bientôt dans l'un de vos prochains cours. Si nous pouvons vous être utile d'une quelconque manière, n'hésitez pas à nous contacter.
$NotificationCertificateTemplate = "Cher/Chère ((user_first_name)), vous avez terminé ((course_title)). Votre note finale est de ((score)). Merci de laisser passer quelques jours avant l'apparition de le visualiser sur notre système. Nous espérons que vous en ayez pleinement profité et que nous vous reverrons bientôt dans l'un de vos prochains cours. Si nous pouvons vous être utile d'une quelconque manière, n'hésitez pas à nous contacter.
Cordialement, ((author_first_name)) ((author_last_name)), ((portal_name))";
$SendCertificateNotifications = "Envoyer les avis de certificat à tous les utilisateurs";
$MailSubjectForwardShort = "Tr";
$ForwardedMessage = "Message transféré";
$ForwardMessage = "Transférer message";
$MyCoursePageCategoryIntroduction = "Vous trouverez ci-dessous la liste des catégories de cours.
$MyCoursePageCategoryIntroduction = "Vous trouverez ci-dessous la liste des catégories de cours.
Cliquez sur l'une pour voir la liste des cours qu'elle contient.";
$FeatureDisabledByAdministrator = "Fonctionnalité désactivée par l'administrateur";
$SubscribeUsersToLpCategory = "Inscrire les utilisateurs à la catégorie";
@ -8046,6 +8073,27 @@ $YouWillReceivedASecondEmail = "Vous allez recevoir un autre mail avec votre mot
$YouReceivedAnEmailWithTheUsername = "Vous avez du recevoir un autre mail avec votre identifiant.";
$TheScormPackageWillBeUpdatedYouMustUploadTheFileWithTheSameName = "Vous devez envoyer un fichier zip du même nom que le fichier SCORM original.";
$YourChoice = "Votre choix";
$MessageQuestionCertainty = "Voici ci dessous vos résultats du test \"<span style=\"font-family: Arial; font-size: 18px; color: green;\">"
. "%exerTitle" //$objExercise->title
. "\"</span>."
. "<br/>Pour consulter le détail des résultats "
. "<br/><br/>1. Connectez vous sur la plate forme Chamilo (identifiant/mot de passe universitaire) : "
. "<a href='"
. " %webPath " // api_get_path(WEB_PATH)
. "'>se connecter à Chamilo : </a>"
. "<br/><br/>2. Puis cliquez sur ce lien %s "
. "voir mes résultats détaillés </a>.<br/><br/>";
$KindRegards = "Cordialement, <br>";
$DoNotReply = "Ne pas répondre";
$ResultAccomplishedTest = "Résultats du test réalisé";
$NonCategory = "Sans catégorie";
$ResultTest = "Votre résultat sur l'ensemble du test";
$CompareLastResult = "Pour comparaison, votre dernier résultat à ce test";
$ResultsbyDiscipline = "Vos résultats discipline par discipline";
$YouNeedToCreateASkillProfile = "Vous devez créer un profil de compétences";
$SkillLevel = "Niveau de compétence";
$Portfolio = "Portfolio";

Loading…
Cancel
Save