From 98efe2a62d1c07a9da84e3dbb006240fd6d1f920 Mon Sep 17 00:00:00 2001 From: Ivan Zambrano Date: Mon, 9 Apr 2018 14:36:02 +0200 Subject: [PATCH 01/30] Question degre de certitude --- main/exercise/answer.class.php | 6 +- main/exercise/exercise.class.php | 487 ++++--- main/exercise/exercise_show.php | 172 ++- main/exercise/exercise_submit.php | 79 +- ...swer_true_false_degree_certainty.class.php | 1151 +++++++++++++++++ main/exercise/question.class.php | 21 +- main/img/icons/22/mccert.png | Bin 0 -> 1000 bytes main/img/icons/22/mccert_na.png | Bin 0 -> 1176 bytes main/img/icons/32/mccert.png | Bin 0 -> 1207 bytes main/img/icons/64/mccert.png | Bin 0 -> 3455 bytes main/img/icons/64/mccert_na.png | Bin 0 -> 3037 bytes main/inc/ajax/exercise.ajax.php | 62 +- main/inc/lib/api.lib.php | 83 +- main/inc/lib/exercise.lib.php | 593 +++++++-- main/inc/lib/exercise_show_functions.lib.php | 99 ++ main/lang/french/trad4all.inc.php | 148 ++- 16 files changed, 2375 insertions(+), 526 deletions(-) create mode 100644 main/exercise/multiple_answer_true_false_degree_certainty.class.php create mode 100644 main/img/icons/22/mccert.png create mode 100644 main/img/icons/22/mccert_na.png create mode 100644 main/img/icons/32/mccert.png create mode 100644 main/img/icons/64/mccert.png create mode 100644 main/img/icons/64/mccert_na.png diff --git a/main/exercise/answer.class.php b/main/exercise/answer.class.php index 0e9c845697a..9a51620fcc7 100755 --- a/main/exercise/answer.class.php +++ b/main/exercise/answer.class.php @@ -844,7 +844,8 @@ public function duplicate($newQuestion, $course_info = null) $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 @@ public function duplicate($newQuestion, $course_info = null) $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)]; } diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index 441d6497a63..23e6e34c0ab 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -2846,7 +2846,7 @@ public function clean_results($cleanLpTests = false, $cleanResultBeforeDate = nu 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 @@ public function manage_answer( $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 @@ public function manage_answer( 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 @@ public function manage_answer( } $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 @@ public function manage_answer( $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 @@ public function manage_answer( $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 @@ public function manage_answer( // 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 .= ''.$user_tags[$i].''; + $answer .= '' . $user_tags[$i] . ''; } else { // adds a tabulation if no word has been typed by the student $answer .= ''; // remove   that causes issue @@ -3975,135 +4035,120 @@ public function manage_answer( } 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 .= ''.$userTags[$i].''; - $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   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 .= ' / '.$realCorrectTags[$i].''; - $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 .= '' . $userTags[$i] . ''; + $calculatedChoice = $userTags[$i]; + } else { + // adds a tabulation if no word has been typed by the student + $answer .= ''; // remove   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 .= ' / '.$realCorrectTags[$i].''; + $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 @@ public function manage_answer( $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 @@ public function manage_answer( ); } 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 @@ public function manage_answer( '.get_lang('Overlap').' '.get_lang('Min').' '.$threadhold1.'
' - .(($final_overlap < 0) ? 0 : intval($final_overlap)).'
+ .(($final_overlap < 0) ? 0 : intval($final_overlap)).' '.get_lang('Excess').' '.get_lang('Max').' '.$threadhold2.'
' - .(($final_excess < 0) ? 0 : intval($final_excess)).'
+ .(($final_excess < 0) ? 0 : intval($final_excess)).' '.get_lang('Missing').' '.get_lang('Max').' '.$threadhold3.'
' - .(($final_missing < 0) ? 0 : intval($final_missing)).'
+ .(($final_missing < 0) ? 0 : intval($final_missing)).' '; if ($next == 0) { @@ -5523,9 +5612,11 @@ public function manage_answer( } } + //if ($origin != 'learnpath') { if ($show_result && $answerType != ANNOTATION) { echo ''; } + // } } unset($objAnswerTmp); @@ -5544,21 +5635,43 @@ public function manage_answer( 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 @@ public function manage_answer( ) { $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 @@ public function manage_answer( } 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 @@ public function manage_answer( 'generated_oral_file' => $generatedFile, ]; - return $return; + return $return_array; } /** @@ -8040,25 +8153,25 @@ private function send_notification_for_open_questions( $course_info = api_get_course_info($courseCode); $msg = get_lang('OpenQuestionsAttempted').'

' - .get_lang('AttemptDetails').' :

' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'
'.get_lang('CourseName').' #course#
'.get_lang('TestAttempted').' #exercise#
'.get_lang('StudentName').' #firstName# #lastName#
'.get_lang('StudentEmail').' #mail#
'; + .get_lang('AttemptDetails').' :

' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'
'.get_lang('CourseName').' #course#
'.get_lang('TestAttempted').' #exercise#
'.get_lang('StudentName').' #firstName# #lastName#
'.get_lang('StudentEmail').' #mail#
'; $open_question_list = null; foreach ($question_list_answers as $item) { $question = $item['question']; @@ -8068,19 +8181,19 @@ private function send_notification_for_open_questions( if (!empty($question) && !empty($answer) && $answer_type == FREE_ANSWER) { $open_question_list .= '' - .'  '.get_lang('Question').'' - .''.$question.'' + .'  '.get_lang('Question').'' + .''.$question.'' .'' .'' - .'  '.get_lang('Answer').'' - .''.$answer.'' + .'  '.get_lang('Answer').'' + .''.$answer.'' .''; } } if (!empty($open_question_list)) { $msg .= '


'.get_lang('OpenQuestionsAttemptedAre').' :

'. - ''; + '
'; $msg .= $open_question_list; $msg .= '

'; $msg1 = str_replace("#exercise#", $this->exercise, $msg); @@ -8145,12 +8258,12 @@ private function send_notification_for_oral_questions( } $oral_question_list .= '
' .'' - .'' - .'' + .'' + .'' .'' .'' - .'' - .'' + .'' + .'' .'
  '.get_lang('Question').''.$question.'  '.get_lang('Question').''.$question.'
  '.get_lang('Answer').''.$answer.$file.'  '.get_lang('Answer').''.$answer.$file.'
'; } } @@ -8158,24 +8271,24 @@ private function send_notification_for_oral_questions( if (!empty($oral_question_list)) { $msg = get_lang('OralQuestionsAttempted').'

'.get_lang('AttemptDetails').' :

' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'' - .'
'.get_lang('CourseName').' #course#
'.get_lang('TestAttempted').' #exercise#
'.get_lang('StudentName').' #firstName# #lastName#
'.get_lang('StudentEmail').' #mail#
'; + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'
'.get_lang('CourseName').' #course#
'.get_lang('TestAttempted').' #exercise#
'.get_lang('StudentName').' #firstName# #lastName#
'.get_lang('StudentEmail').' #mail#
'; $msg .= '
'.sprintf(get_lang('OralQuestionsAttemptedAreX'), $oral_question_list).'
'; $msg1 = str_replace("#exercise#", $this->exercise, $msg); $msg = str_replace("#firstName#", $user_info['firstname'], $msg1); diff --git a/main/exercise/exercise_show.php b/main/exercise/exercise_show.php index 4cfd46f1ea0..b779c36bc63 100755 --- a/main/exercise/exercise_show.php +++ b/main/exercise/exercise_show.php @@ -64,6 +64,9 @@ $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 @@ $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[] = ['url' => '#', 'name' => get_lang('Result')]; $this_section = SECTION_COURSES; + $htmlHeadXtra[] = ''; $htmlHeadXtra[] = ''; $htmlHeadXtra[] = ''; @@ -222,7 +223,7 @@ function getFCK(vals, marksid) { } } -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 @@ function getFCK(vals, marksid) { 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 @@ function getFCK(vals, marksid) { } // 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 "
 
"; } @@ -367,6 +370,7 @@ function getFCK(vals, marksid) { $exercise_content = ''; $category_list = []; $useAdvancedEditor = true; + if (!empty($maxEditors) && count($questionList) > $maxEditors) { $useAdvancedEditor = false; } @@ -430,6 +434,25 @@ function getFCK(vals, marksid) { $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 ' @@ -757,6 +780,8 @@ function getFCK(vals, marksid) { } $feedback_form->setDefaults($default); $feedback_form->display(); + + echo ''; if ($allowRecordAudio && $allowTeacherCommentAudio) { @@ -923,31 +948,46 @@ function getFCK(vals, marksid) { $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 .= '
'; - $my_total_score_temp = $totalScore; - if ($objExercise->selectPropagateNeg() == 0 && $my_total_score_temp < 0) { - $my_total_score_temp = 0; + $totalScoreText .= '
'; + $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 .= '
'; + + 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 .= '
'; } } +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 @@ function getFCK(vals, marksid) { ); } -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 @@ function getFCK(vals, marksid) { + ?> title . "\""); + // message sended to the student + $message = get_lang('Dear') . ' ' . $recipient_name . ",

"; + //calcul du chemmin sans les script php + $url = $_SERVER['SCRIPT_NAME']; + $pos = strripos($url, "/"); + + $path = substr($url, 0, $pos); + + $message .= get_lang('MessageQuestionCertainty'); + $exerciseLink = ""; + $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 @@ $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 @@ function updateDuration() { } $(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 @@ function updateDuration() { });*/ $("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 @@ function updateDuration() { $(\'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 @@ function updateDuration() { $(\'button[name="validate_all"]\').on(\'click\', function (e) { e.preventDefault(); - e.stopPropagation(); + e.stopPropagation(); + validate_all(); }); @@ -1190,6 +1252,9 @@ function save_now(question_id, url_extra) { //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 @@ function save_now(question_id, url_extra) { 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).'\'); diff --git a/main/exercise/multiple_answer_true_false_degree_certainty.class.php b/main/exercise/multiple_answer_true_false_degree_certainty.class.php new file mode 100644 index 00000000000..4215a3b8a0d --- /dev/null +++ b/main/exercise/multiple_answer_true_false_degree_certainty.class.php @@ -0,0 +1,1151 @@ +type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY; + $this->isContent = $this->getIsContent(); + $this->optionsTitle = [1 => 'langAnswers', 2 => 'DegreeOfCertainty']; + $this->options = [ + 1 => 'True', + 2 => 'False', + 3 => '50%', + 4 => '60%', + 5 => '70%', + 6 => '80%', + 7 => '90%', + 8 => '100%' + ]; + } + + /** + * function which redefines Question::createAnswersForm + * @param FormValidator $form + */ + public function createAnswersForm($form) { + $nbAnswers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4; + // The previous default value was 2. See task #1759. + $nbAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); + + $courseId = api_get_course_int_id(); + $objEx = $_SESSION['objExercise']; + $renderer = & $form->defaultRenderer(); + $defaults = []; + + $html = '
'; + + // show column comment when feedback is enable + if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + $html .=''; + } + $html .= ''; + $form->addElement('label', get_lang('Answers') . '
', $html); + + $correct = 0; + $answer = null; + if (!empty($this->id)) { + $answer = new Answer($this->id); + $answer->read(); + if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) { + $nbAnswers = $answer->nbrAnswers; + } + } + + $form->addElement('hidden', 'nb_answers'); + $boxesNames = []; + + if ($nbAnswers < 1) { + $nbAnswers = 1; + Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer')); + } + + // Can be more options + $optionData = Question::readQuestionOption($this->id, $courseId); + + + for ($i = 1; $i <= $nbAnswers; ++$i) { + + $renderer->setElementTemplate( + '
', + 'correct[' . $i . ']' + ); + $renderer->setElementTemplate( + '', + 'counter[' . $i . ']' + ); + $renderer->setElementTemplate( + '', + 'answer[' . $i . ']' + ); + $renderer->setElementTemplate( + '', + 'comment[' . $i . ']' + ); + + $answerNumber = $form->addElement('text', 'counter[' . $i . ']', null, 'value="' . $i . '"'); + $answerNumber->freeze(); + + if (is_object($answer)) { + $defaults['answer[' . $i . ']'] = $answer->answer[$i]; + $defaults['comment[' . $i . ']'] = $answer->comment[$i]; + $defaults['weighting[' . $i . ']'] = float_format($answer->weighting[$i], 1); + + $correct = $answer->correct[$i]; + $defaults['correct[' . $i . ']'] = $correct; + + $j = 1; + if (!empty($optionData)) { + foreach ($optionData as $id => $data) { + $form->addElement('radio', 'correct[' . $i . ']', null, null, $id); + $j++; + if ($j == 3) { + break; + } + } + } + } else { + $form->addElement('radio', 'correct[' . $i . ']', null, null, 1); + $form->addElement('radio', 'correct[' . $i . ']', null, null, 2); + + $defaults['answer[' . $i . ']'] = ''; + $defaults['comment[' . $i . ']'] = ''; + $defaults['correct[' . $i . ']'] = ''; + } + + $boxesNames[] = 'correct[' . $i . ']'; + $form->addElement( + 'html_editor', + 'answer[' . $i . ']', + null, + 'style="vertical-align:middle"', + array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100')); + $form->addRule('answer[' . $i . ']', get_lang('ThisFieldIsRequired'), 'required'); + + // show comment when feedback is enable + if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + $form->addElement('html_editor', + 'comment[' . $i . ']', + null, + 'style="vertical-align:middle"', + array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100')); + } + $form->addElement('html', ''); + } + + $form->addElement('html', '
' + . get_lang('Number') + . '' + . get_lang('True') + . '' + . get_lang('False') + . '' + . get_lang('Answer') + . '' . get_lang('Comment') . '
{error}
{element}
{error}
{element}
{error}
{element}
{error}
{element}
'); + $form->addElement('html', '
'); + + // 3 scores + $form->addElement('text', 'option[1]', get_lang('Correct'), array('class' => 'span1', 'value' => '1')); + $form->addElement('text', 'option[2]', get_lang('Wrong'), array('class' => 'span1', 'value' => '-0.5')); + + $form->addElement('hidden', 'option[3]', 0); + + $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required'); + $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required'); + + $form->addElement('html', ''); + $form->addElement('hidden', 'options_count', 3); + $form->addElement('html', '


'); + + //Extra values True, false, Dont known + if (!empty($this->extra)) { + $scores = explode(':', $this->extra); + if (!empty($scores)) { + for ($i = 1; $i <= 3; $i++) { + $defaults['option[' . $i . ']'] = $scores[$i - 1]; + } + } + } + + global $text, $class; + if ($objEx->edit_exercise_in_lp == true) { + + $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"'); + $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"'); + $form->addElement('submit', 'submitQuestion', $text, 'class="' . $class . '"'); + + } + $renderer->setElementTemplate('{element} ', 'lessAnswers'); + $renderer->setElementTemplate('{element} ', 'submitQuestion'); + $renderer->setElementTemplate('{element} ', 'moreAnswers'); + $form->addElement('html', ''); + $defaults['correct'] = $correct; + + if (!empty($this->id)) { + $form->setDefaults($defaults); + } else { + //if ($this -> isContent == 1) { + $form->setDefaults($defaults); + //} + } + $form->setConstants(['nb_answers' => $nbAnswers]); + } + + /** + * abstract function which creates the form to create / edit the answers of the question + * @param FormValidator $form + * @param Exercise $exercise + */ + public function processAnswersCreation($form, $exercise) { + $questionWeighting = $nbrGoodAnswers = 0; + $objAnswer = new Answer($this->id); + $nbAnswers = $form->getSubmitValue('nb_answers'); + + $courseId = api_get_course_int_id(); + + $correct = []; + $options = Question::readQuestionOption($this->id, $courseId); + + + if (!empty($options)) { + foreach ($options as $optionData) { + $id = $optionData['id']; + unset($optionData['id']); + Question::updateQuestionOption($id, $optionData, $courseId); + } + } else { + for ($i = 1; $i <= 8; $i++) { + $lastId = Question::saveQuestionOption($this->id, $this->options[$i], $courseId, $i); + $correct[$i] = $lastId; + } + } + + /* Getting quiz_question_options (true, false, doubt) because + it's possible that there are more options in the future */ + + $newOptions = Question::readQuestionOption($this->id, $courseId); + + $sortedByPosition = []; + foreach ($newOptions as $item) { + $sortedByPosition[$item['position']] = $item; + } + + /* Saving quiz_question.extra values that has the correct scores of + the true, false, doubt options registered in this format + XX:YY:ZZZ where XX is a float score value. */ + $extraValues = []; + + for ($i = 1; $i <= 3; $i++) { + $score = trim($form->getSubmitValue('option[' . $i . ']')); + $extraValues[] = $score; + } + $this->setExtra(implode(':', $extraValues)); + + for ($i = 1; $i <= $nbAnswers; $i++) { + $answer = trim($form->getSubmitValue('answer[' . $i . ']')); + $comment = trim($form->getSubmitValue('comment[' . $i . ']')); + $goodAnswer = trim($form->getSubmitValue('correct[' . $i . ']')); + if (empty($options)) { + //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered + $goodAnswer = $sortedByPosition[$goodAnswer]['id']; + } + $questionWeighting += $extraValues[0]; //By default 0 has the correct answers + $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i); + } + + // saves the answers into the data base + $objAnswer->save(); + + // sets the total weighting of the question + $this->updateWeighting($questionWeighting); + $this->save($exercise); + } + + /** + * @param int $feedbackType + * @param int $counter + * @param float $score + * @return null|string + */ + function return_header($feedbackType = null, $counter = null, $score = null) { + $header = parent::return_header($feedbackType, $counter, $score); + $header .= '' + ; + if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { + $header .= ''; + } else { + $header .= ''; + } + $header .= ''; + return $header; + } + + /** + * Method to recovery color to show by precision of the student's answer + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * @return string + */ + function getColorResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) + return '#088A08'; + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) + return '#A9F5A9'; + if ($studentDegreeChoicePosition == 3) + return '#FFFFFF'; + } else { + if ($studentDegreeChoicePosition >= 6) + return '#FE2E2E'; + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) + return '#F6CECE'; + if ($studentDegreeChoicePosition == 3) + return '#FFFFFF'; + } + } + + /** + * Return the color code for student answer + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * @return int + */ + function getStatusResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) + return self::LEVEL_DARKGREEN; + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) + return self::LEVEL_LIGHTGREEN; + if ($studentDegreeChoicePosition == 3) + return self::LEVEL_WHITE; + } else { + if ($studentDegreeChoicePosition >= 6) + return self::LEVEL_DARKRED; + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) + return self::LEVEL_LIGHTRED; + if ($studentDegreeChoicePosition == 3) + return self::LEVEL_WHITE; + } + } + + /** + * Method to recovery lable for codes colors + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * @return string + */ + public function getCodeResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) + return get_lang('langVerySure'); + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) + return get_lang('langPrettySur'); + if ($studentDegreeChoicePosition == 3) + return get_lang('langIgnorance'); + } else { + if ($studentDegreeChoicePosition >= 6) + return get_lang('langVeryUnsure'); + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) + return get_lang('langUnsure'); + if ($studentDegreeChoicePosition == 3) + return get_lang('langIgnorance'); + } + + } + + /** + * Method to show the code color and his meaning for the test result + */ + public static function showColorCode() { + ?> +
' + . get_lang("Choice") + . '' + . get_lang("ExpectedChoice") + . '' + . get_lang("Answer") + . '' + . get_lang("YourDegreeOfCertainty") + . ' ' . get_lang("Comment") . ' 
+ + + + + + + + + + + + + + + + + + + + + +
  + : + +
  + : + +
  + : + +
  + : + +
  + : + +

+ + gather_questions_categories == 1) { // original + $groupCategoriesByBracket = true; + } else { + $groupCategoriesByBracket = false; + } + + if ($groupCategoriesByBracket) { + $scoreList = []; + $categoryPrefixList = []; // categoryPrefix['Math'] = firstCategoryId for this prefix + // rebuild $scoreList factirizing datas with caregory prefix + foreach ($scoreListAll as $categoryId => $scoreListForCategory) { + $objCategory = new Testcategory(); + $objCategoryNum = $objCategory->getCategory($categoryId); + preg_match("/^\[([^]]+)\]/", $objCategoryNum->name, $matches); + + if (count($matches) > 1) { + // check if we have already see this prefix + if (array_key_exists($matches[1], $categoryPrefixList)) { + // add the result color for this entry + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKGREEN] += $scoreListForCategory[self::LEVEL_DARKGREEN]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTGREEN] += $scoreListForCategory[self::LEVEL_LIGHTGREEN]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_WHITE] += $scoreListForCategory[self::LEVEL_WHITE]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTRED] += $scoreListForCategory[self::LEVEL_LIGHTRED]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKRED] += $scoreListForCategory[self::LEVEL_DARKRED]; + + } else { + $categoryPrefixList[$matches[1]] = $categoryId; + $scoreList[$categoryId] = $scoreListAll[$categoryId]; + } + } else { + // dont matche the prefix '[math] Math category' + $scoreList[$categoryId] = $scoreListAll[$categoryId]; + } + } + } else { + $scoreList = $scoreListAll; + } + + + // get the max height of item to have each table the same height if displayed side by side + foreach ($scoreList as $categoryId => $scoreListForCategory) { + $testCategorie = new TestCategory(); + $categorieQuestionName = $testCategorie->getCategory($categoryId)->name; + list($null, $height) = self::displayDegreeChart( + $scoreListForCategory, + 300, + '', + 1, + 0, + false, + true, + groupCategoriesByBracket + ); + if ($height > $maxHeight) { + $maxHeight = $height; + } + } + + if (count($scoreList) > 1) { + $boxWidth = $sizeRatio * 300 * 2 + 54; + } else { + $boxWidth = $sizeRatio * 300 + 54; + } + + $html = '
'; + $html .= '

' . $title . '

'; + + // get the html of items + $i = 0; + foreach ($scoreList as $categoryId => $scoreListForCategory) { + $oCategory = new Testcategory(); + $categorieQuestionName = $oCategory->getCategory($categoryId)->name; + + if ($categorieQuestionName == '') { + $categoryName = get_lang('NonCategory'); + } else { + $categoryName = $oCategory->name; + } + + $html .= '
'; + $html .= self::displayDegreeChart( + $scoreListForCategory, + 300, + $categoryName, + 1, + $maxHeight, + false, + false, + $groupCategoriesByBracket + ); + $html .= '
'; + + if ($i == 1) { + $html .= '
 
'; + $i = 0; + } else { + $i++; + } + } + + + return $html . '
 
'; + } + + /** + * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions + * @param $scoreList + * @param int $sizeRatio + * @return string + */ + public static function displayDegreeChart( + $scoreList, + $widthTable, + $title = '', + $sizeRatio = 1, + $minHeight = 0, + $displayExplanationText = true, + $returnHeight = false, + $groupCategoriesByBracket = false, + $numberOfQuestions = 0 + ) { + $topAndBottomMargin = 10; + + $colorList = [self::LEVEL_DARKRED, + self::LEVEL_LIGHTRED, + self::LEVEL_WHITE, + self::LEVEL_LIGHTGREEN, + self::LEVEL_DARKGREEN + ]; + + + // get total attempt number + $highterColorHeight = 0; + + foreach ($scoreList as $color => $number) { + if ($number > $highterColorHeight) { + $highterColorHeight = $number; + } + } + + $totalAttemptNumber = $numberOfQuestions; + + $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2; + if ($verticalLineHeight < $minHeight) { + $minHeightCorrection = $minHeight - $verticalLineHeight; + $verticalLineHeight += $minHeightCorrection; + } + + // draw chart + $html = ''; + + if ($groupCategoriesByBracket) { + $title = api_preg_replace("/[^]]*$/", "", $title); + $title = ucfirst(api_preg_replace("/[\[\]]/", "", $title)); + } + + $affiche = (strpos($title, "ensemble") > 0) ? + $title . "
($totalAttemptNumber questions)" : + $title; + $textSize = ( + strpos($title, "ensemble") > 0 || + strpos($title, "votre dernier résultat à ce test") > 0 + ) ? 100 : 80; + + if ($displayExplanationText) { + // global chart + $classGlobalChart = "globalChart"; + } else { + $classGlobalChart = ""; + } + + $html .= '' + ; + $html .= '' + ; + + $nbResponsesInc = (isset($scoreList[4]) || isset($scoreList[5])) ? $scoreList[4] + $scoreList[5] : 0; + $nbResponsesIng = (isset($scoreList[3])) ? $scoreList[3] : 0; + $nbResponsesCor = (isset($scoreList[1]) || isset($scoreList[2])) ? $scoreList[1] + $scoreList[2] : 0; + + $colWidth = $widthTable / 5; + + $html .= ' + + + + '; + $html .= ''; + + foreach ($colorList as $i => $color) { + if (array_key_exists($color, $scoreList)) { + $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom + } else { + $scoreOnBottom = 0; + } + + $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2 ; + + if ($i == 1 || $i == 2) { + $html .= ''; + } + + $html .= ''; + + if ($displayExplanationText) { + // affichage texte histogramme + $explainHistoList = array( + 'langVeryUnsure', + 'langUnsure', + 'langIgnorance', + 'langPrettySur', + 'langVerySure'); + $html .= ''; + $i = 0; + foreach ($explainHistoList as $explain) { + if ($i == 1 || $i == 2) { + $class = "borderRight"; + } else { + $class = ""; + } + $html .= ''; + $i++; + } + $html .= ''; + } + + $html .='
' + . $affiche + . '
'. + get_lang('langWrongsAnswers').' : '.$nbResponsesInc.' + '. + get_lang('langIgnoranceAnswers').' : '.$nbResponsesIng.' + '. + get_lang('langCorrectsAnswers').' : '.$nbResponsesCor.' +
' + ; + } else { + $html .= '' + ; + } + $html .= '
' + . $scoreOnBottom + . '
 
' + ; + $html .= '
' + ; + $html .= get_lang($explain); + $html .= '
'; + + if ($returnHeight) { + return array($html, $verticalLineHeight); + } else { + return $html; + } + } + + /** + * return previous attempt id for this test for student, 0 if no previous attempt + * @param $exeId + * @return int + */ + public static function getPreviousAttemptId($exeId) { + $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + $sql = "SELECT * + FROM $tblTrackEExercise + WHERE exe_id = " . intval($exeId); + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + // if we cannot find the exe_id + return 0; + } + + $data = Database::fetch_assoc($res); + $courseCode = $data['exe_cours_id']; + $exerciseId = $data['exe_exo_id']; + $userId = $data['exe_user_id']; + $attemptDate = $data['exe_date']; + + if ($attemptDate == "0000-00-00 00:00:00") { + // incomplete attempt, close it before continue + return 0; + } + + // look for previous attempt + $sql = "SELECT * + FROM $tblTrackEExercise + WHERE c_id = '" . $courseCode . "' + AND exe_exo_id = " . intval($exerciseId) . " + AND exe_user_id = " . intval($userId) . " + AND status = '' + AND exe_date > '0000-00-00 00:00:00' + AND exe_date < '" . $attemptDate . "' + ORDER BY exe_date DESC"; + + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + // no previous attempt + return 0; + } + + $data = Database::fetch_assoc($res); + return $data['exe_id']; + } + + /** + * return an array of number of answer color for exe attempt for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + * e.g. + * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0] + * @param $exeId + * @return array + */ + public static function getColorNumberListForAttempt($exeId) { + $result = [self::LEVEL_DARKGREEN => 0, + self::LEVEL_LIGHTGREEN => 0, + self::LEVEL_WHITE => 0, + self::LEVEL_LIGHTRED => 0, + self::LEVEL_DARKRED => 0 + ]; + + $attemptInfoList = self::getExerciseAttemptInfo($exeId); + + foreach ($attemptInfoList as $i => $attemptInfo) { + $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); + $oQuestion->read($attemptInfo['question_id']); + if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); + if ($answerColor) { + $result[$answerColor] ++; + } + } + } + return $result; + } + + /** + * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + * for each question category + * + * e.g. + * [ + * (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12] + * (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8] + * (categoryId=)0 => [LEVEL_DARKGREEN => 1, LEVEL_LIGHTGREEN => 2, LEVEL_WHITE => 6, LEVEL_LIGHTRED => 1, LEVEL_DARKTRED => 9] + * ] + * @param $exeId + * @return array + */ + public static function getColorNumberListForAttemptByCategory($exeId) { + $result = array(); + $attemptInfoList = self::getExerciseAttemptInfo($exeId); + + foreach ($attemptInfoList as $i => $attemptInfo) { + $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); + $oQuestion->read($attemptInfo['question_id']); + if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']); + + if (!array_key_exists($questionCategory, $result)) { + $result[$questionCategory] = array(); + } + + $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); + if ($answerColor) { + $result[$questionCategory][$answerColor] ++; + } + } + } + return $result; + } + + /** + * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false + * @param $exeId + * @param $questionId + * @param $position + * @return bool + */ + public static function getAnswerColor($exeId, $questionId, $position) { + $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position); + + if (count($attemptInfoList) != 1) { + // havent got the answer + return 0; + } + + $answerCodes = $attemptInfoList[0]['answer']; + + // student answer + $splitAnswer = preg_split("/:/", $answerCodes); + // get correct answer option id + $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]); + if ($correctAnswerOptionId == 0) { + // error returning the correct answer option id + return 0; + } + + // get student answer option id + $studentAnswerOptionId = $splitAnswer[1]; + + // we got the correct answer option id, let's compare ti with the student answer + $percentage = self::getPercentagePosition($splitAnswer[2]); + if ($studentAnswerOptionId == $correctAnswerOptionId) { + // yeah, student got correct answer + switch ($percentage) { + case 3 : + return self::LEVEL_WHITE; + case 4 : + case 5 : + return self::LEVEL_LIGHTGREEN; + case 6 : + case 7 : + case 8 : + return self::LEVEL_DARKGREEN; + default : + return 0; + } + } else { + // bummer, wrong answer dude + switch ($percentage) { + case 3 : + return self::LEVEL_WHITE; + case 4 : + case 5 : + return self::LEVEL_LIGHTRED; + case 6 : + case 7 : + case 8 : + return self::LEVEL_DARKRED; + default : + return 0; + } + } + } + + /** + * Return the position of certitude %age choose by student + * @param $optionId + * @return int + */ + public static function getPercentagePosition($optionId) { + $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION); + $courseId = api_get_course_int_id(); + $sql = "SELECT position + FROM $tblAnswerOption + WHERE c_id = " . intval($courseId) . " + AND id = " . intval($optionId); + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + return 0; + } + + $data = Database::fetch_assoc($res); + return $data['position']; + } + + /** + * return the correct id from c_quiz_question_option for question idAuto + * @param $idAuto + * @return int + */ + public static function getCorrectAnswerOptionId($idAuto) { + $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER); + $courseId = api_get_course_int_id(); + $sql = "SELECT correct + FROM $tblAnswer + WHERE c_id = " . intval($courseId) . " + AND id_auto = " . intval($idAuto); + + $res = Database::query($sql); + $data = Database::fetch_assoc($res); + if (Database::num_rows($res) > 0) { + return $data['correct']; + } else { + return 0; + } + } + + /** + * return an array of exe info from track_e_attempt + * @param $exeId + * @param int $questionId + * @param int $position + * @return array + */ + public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1) { + $result = array(); + $and = ''; + + if ($questionId >= 0) { + $and .= " AND question_id = " . intval($questionId); + } + if ($position >= 0) { + $and .= " AND position = " . intval($position); + } + + $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + $cId = api_get_course_int_id(); + $sql = "SELECT * FROM $tblExeAttempt + WHERE c_id = $cId + AND exe_id = $exeId + $and"; + + $res = Database::query($sql); + while ($data = Database::fetch_assoc($res)) { + $result[] = $data; + } + return $result; + } + + + public static function getNumberOfQuestionsForExeId($exeId) + { + $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + $sql = "SELECT exe_exo_id + FROM $tableTrackEExercise + WHERE exe_id=".intval($exeId); + $res = Database::query($sql); + $data = Database::fetch_assoc($res); + $exerciseId = $data['exe_exo_id']; + + $objectExercise = new Exercise(); + $objectExercise->read($exerciseId); + + return $objectExercise->get_count_question_list(); + } + + /** + * Display student chart results for these question types + * @param $exeId + * @return string + */ + public static function displayStudentsChartResults($exeId, $objExercice) { + + $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId); + + $globalScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt($exeId); + $html = MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( + $globalScoreList, + 600, + get_lang('ResultTest'), + 2, + 0, + true, + false, + false, + $numberOfQuestions + ) + . "
" + ; + + $previousAttemptId = MultipleAnswerTrueFalseDegreeCertainty::getPreviousAttemptId($exeId); + if ($previousAttemptId > 0) { + $previousAttemptScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt( + $previousAttemptId + ); + $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( + $previousAttemptScoreList, + 600, + get_lang('CompareLastResult'), + 2 + ) + . "
" + ; + } + + $categoryScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttemptByCategory($exeId); + $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChartByCategory( + $categoryScoreList, + get_lang('ResultsbyDiscipline'), + 1 + ,$objExercice + ) + . "
" + ; + + return $html; + } + + } diff --git a/main/exercise/question.class.php b/main/exercise/question.class.php index d96896c7e5a..ea8a37046a0 100755 --- a/main/exercise/question.class.php +++ b/main/exercise/question.class.php @@ -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 @@ public static function get_question_type_list() 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 @@ public function return_header($exercise, $counter = null, $score = []) '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( diff --git a/main/img/icons/22/mccert.png b/main/img/icons/22/mccert.png new file mode 100644 index 0000000000000000000000000000000000000000..5775afe1e51d2c69a573b4fe41135e2c70cf46a5 GIT binary patch literal 1000 zcmV>P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf00v@9M??Vs0RI60 zpuMM)00007bV*G`2jB!14gfG@kge$e00US_L_t(YOSP3-XdGn}$A2@kvzxUsEsd#d zDosjaF4#7Lh$s!E5fR0LR0JPH@X3b?BBFSCQ54^N5TTIzltLA;p!iT)k|-w7#uBS( zN=agB)?C_bnq=K%FEcxr&$GJ|lSybz3;u?W*>k?x|C~AJ%o$Ay{11eLQ#qTVnMHIh zaBLFS^XX{b9asTH;T0|>=9E=%0&DYRtb#gyemJno=z)F-Gollbb*IEklUz1~V_Sg- zBEh+YCI^z3Qy0hRAHU9%Ef4VGBaIAA&U5DS1Xb}EueR@JdSQeMe+@_wCXQqCeA`QC zS}~y29EOA=hQ^IlmY2WznSBT9xiUCLTWvKxS0{PzxktH_m}BtI1qPEp@YZ+lN~rRu z96Zr@n1~*d3JVvpq!0%icJtVt8b0g2Oe|vHD!;Us&fAz;lxH4(mde)cL?vR&vDmS7 z2cAD)x@Lt?LS0``xBXs@Htu3-e3s8U+Ni6kqW!^IzUUd^k7Sy?_g7IVM@zh!W?8NA z77;OuO%SLAlxtY#x9NH1d0t@Mn&qX8@`C2^Y)|D2t~%L$K@}{k>=Z%~8@kTyQl2-z z?xXXkVctJ|p2dvC+uskMz3?gZADrad-xHX2mZk9#mabisHHz|Fsav@DL&C)^+x2+7 zVJEL0-cNf|Eq~`MQkKIzZycdPUV^0UqK}SZbarB%IDv8eIAo=Q64Y8kmOKF!rXfWt zaAkU)g{;jsX|bJ^F?yvle!MzGQ_WVi8wfrs&x@>$g%JHYBrr!{bMug zdMZ=$JFcgO6G=63BUQ3p+gAC-MP;Sa%1WhF-f>k|&p;^08-xp+DBgN3xpCL+il=l_ zRybF8%c_c#$ILIom#@RQkK~O?L%|L<@0?ZPg&A5;9UwY6BEQeVhfU(#@M3P7e}(<- zF09N$s3W~lF#x;T;ny?4?tincCj#MOf5#I<_uWJ*h+Qo!_KP^DkRedIK7z6L-vz;>@9UftK(EeGTc0Lj{KgzXfhgaMR9&lBvW*E_ww_Q+P{ODf5m8WLCay$BT&bW4f*W^6A&47!Ajr6wYy?3N zg2=1})FJ4`5Fy}V7P?Tx4~UYlpi z-qY2<|HW2US2OmLOr6Wi%frph&A)IQm-imdqtWP%D2hFPzyD%-diwPVM@L7LQmW8* zw6(RhU?yM8(+;Q8S)|kHo{dhfCI~`FRaI5fs{jDdkII8glyc7vrj$aGBzV1EP)fmZ z9C~|uq19?ZDTT-5K_n6Z0CabE!)P=j7!1Pa^MTSYdm!XX5Zl|^p9l5a3qlAM78Vc= zhmlMsVX;`Sw6uh&sVS_lucNcG6XoUQ0D!rhAOMUM{2;0i@Gu3=R$= z5D4J(^b{2p6#xK5QT`Dv05F+Mn4O&k$NjZzDwWC|Kv!2691aH{oA`vRfvU)`#5lShg zUayzd*4DOW6@iy3s%hGCFOrBGQ}iJqPwP)ac} zGJ<3>sg~&4+8Sh8Mko{l&+}^NQ>hf{>+5sNfnYEQyWOs~mzI_Q02db*;5ZJ2g@v%& z?O0h^!PV6jN=izg)9JwTyc(%*O2VgMeryv$(9qC;{{DU(A0HzW3V{%UU@(a7?d`9G zh*FBl$;sRR$g&JsmQ@PU=`;YKw6qil2M1tT7T4F;h{xj)1Oa}(AGf!+>bOjKl9d#X zjg7(M@gSW}gXekJY&K9zQC3!lnVA_}UtgoTx*BzLbto<_1|bA}eSL3s{%R5y6ck`+ zXei@*v)K%@+5Gg22SE_Bswn2)J}Lco0Z>X2kH@o@(r*PIiXz9dEZlB478e)aoJ{Wm zps}%$)oQiDhlhtB3&3u-~pe0=;TLWp#7a)QCZLA18ELY8GzR#w98cH{p3{{7F1j}ODc!{3=q zrXK}CKz@EcRTPCV41=1Q8i=BZXfz6+&xe+lmX878a=HF+xm?6%vwd&1S`U0a9{_;o zc`yv~qMpCS5{U#jjw7!sp~+-Ah(@DGBofHa&!>95o;+4XTU%S!jtL= literal 0 HcmV?d00001 diff --git a/main/img/icons/32/mccert.png b/main/img/icons/32/mccert.png new file mode 100644 index 0000000000000000000000000000000000000000..56499baf4113297fcfdedd54ec4392c0ffec315d GIT binary patch literal 1207 zcmV;o1W5adP)muyv7rsodIL)l3neOnfUyuYfFUV~7c`M5 z541iQqisly1~nF9lr+T9qG@VLQ(u5W2p1E;(u5RfVXV`_%yc@_Gjp~NQwBmi)E+ud zuD7$--e>)L{r_5P!~ex6{Y%K7i! zT|51O!{_>?l+uv1XuA(~4^0(Ixp!gHzHVn)f-Pot%vzQ+IXyGCuxMHUfRu64fojzz zQL4t;ETzQl3-C?XpBPeNRTXM0OGwhJNT8wPG&ekcq=e1S7m}at#5LmL+|@G}LPiB9 zP*`64Vr)>c96|`z?d_mjABT{^nu3SevagE+Z@)xc+X-sQ7cxI16@WEOzwt}$DtZQb z*x0@i51#0M9MXZm*gtas09Qu?WXwt6ow7$cc72$D9tL1w#1{FK(lD1Thp-^ z7Q}>vQk3NT({ewj9yVxPwuno^9)9f|U}a(=07eXz6y!Y4o~?UOGz$>fV+5sn0NbC+ z=k>-mPy{G~wHqQLe(Sjc)_>hjMsflm5h8NiaYJV~=tdg1g#^6-Umr$eBO(xpZZ@n|XlXGAz!%i<2Xz!h5Y)qj!jW5LCOde){Un3I zaXK!$AgE)vs)T$#?7h9%z1|1_ArP8oE(20ZzN%Tum%pDu4;v)dRGMm*Af=?{>3nY7 z@-uX6l!8aHSYG`k0G6U6{B?DVOL->)ih|v&2-6ZYK3=_eO8?#Ed7E!XRu+y`t7cX> zvoYm_Fh99x1;B$?Yyi>#&&@c#4q^Z(JbzR*EH-G~3A>zk)n1$)DfcvA3;vx$o({Kx zbB;n5aAN@Kb71WOSh_xb8IV;VAUu9mYf5%}q0re3niUS_L3(i{cpT`60ub#WE7?6} zN%H!Rs1pFeu@489eiH zd;o~ET;VL@uN8|H=dS2Ip&T<1LI=%&;G3}P`v(d%>L0_Rs$$ws_*n7j6C*=&33y7# zPCOz9Qa%#%Qa)vP|3dz$+Ge6j!QZ~1Y(3N_lANi1(*lsEc+Gjzb;z}@=P>h)%4aXw z_cja`+PczuIMq2ga{vhZZdZ8BGxF2Lqn$VZ^Fdj`3q~~`%of+LCN3~{Fur{d{slZZ V-$asR$!7on002ovPDHLkV1fpc75D%E literal 0 HcmV?d00001 diff --git a/main/img/icons/64/mccert.png b/main/img/icons/64/mccert.png new file mode 100644 index 0000000000000000000000000000000000000000..de0f1870a507537694bfe99d8237c5ccbe36a884 GIT binary patch literal 3455 zcmaJ^c|4SB8-7PImh5CH8H3Z2WoBeB!w55oEQ3kPl3@lDX2#4gW8ak|eI}(Oob1_- zlqHp%M2e#+St`u2Rb(k;t9;{})A_zXzP|VOd*5gIUDtJA_x;?@A8!WU*-lbiRU7~S zN&AC1H^FGR^@@rJzEza)QNf_XvhifO(*jv+B7+QAk!b#8hY@ent!)?-@+X89 zf`R^J%F_uC!O|FH2+{zq9{@K-K#YwH5Jqs65lRnY2uHwS2tyd$L>~c1BTdk71my1r zDu~7)1)|+>wtvSGtT51E7K@IC!PsoJ0eimzjS&Pxpin3n+z@7Hs4qb1Goz?1B1fOf z)cmf1BQpaS6grDSqe8Y6iT<<*76vMC`d12J^nYZj%)iSdC>V@Gq{9#f@U4`-1D%}y zKQt`tA2gHYM*ffA|0&EQMA6AGH!_nJ!3Yo>T%hJwC^{O;AQM?M27yKk{a!_UFpWiH z2Gi&etUJ;G0XagUl4xw^pLi!Hv^|x{B2oj$_BaewpkP3ukkH0RTT>(whk%=)_9GBB z#-^sWrZ_7c7KcJ2Y)njX-?=ziKtvds%KFYF{fBG#L+(~9gwX|&abyN1l1#E?(83^p zri`Zi&hCSy zjZnSpFW0UwKaY&64%2-WS@`Nn*RF~v;m5iy=_=66e+c8{NU4{I20?wpEBRJIBI!Gi zM#@ZnT2o$|zQT{aw-A@Gun_nAZs!Z+SC1Y}NHuu?^DIE2iLuyLC#6lfS=E`N^+|gk zKk6aDU(+>sdczr}dZFCu?Nrr5ly{sxeSZBnZsR__`oubGpwmXRNP((8L)5Jw@)?S# z>i5M5_8yo)AE3WJuXA<1z!7*Jq&Jl3D}3?LF2xcbR*|$ z0342gPoB)X8gPw_LjcfGc0BT@{I{ zJq&IX>hHF$DAOPNOl!NbVcN6rdh&F@H7C#2>q&V?EsfxBq$Q-@XinDh6(Nq+y>ED3 zVRK{19*HjP;t`uuX!kb_-LdcGM8t`9YR6l za`LZVXk#2y)4N?-#s>o3<;^DE=gpI|;J_ErwuGVrwaK~{^`@Y4qr9LZNFjmD%&!QCWyeSMmH|`U6s>5m86gSk! z2e*4k=485zvP9Lh-e&uUC|Z2^7Mdu>)rtKY^Aq7@=4)*c*>Oo`hMbzbqkXF=#(baH z75k#!C#q)ej$C#rmg|siFWI;~QHV>8^j{oSu{$BR{guaFw;1+a6uG|wex;#9+@T4)9Y$9H`QW7g`Zn~?2%)3AA72J#%jQ(3s-b+ zHgBb8W7VJ}L%iiJQ1ANX2s#;6RN(8g;PXve{xwxRM$DjmBwxe&6AX1Zs4Gnk@Obhi zve&mxtG04{`Gj`-#StaS1UGs5aiuLsbHc0|b?)Rohm-LZ{6z@)l=cL;IH4){9{Bu4 zu3X6({}w5>8t}6+AO%Ly2prJR=ij1sTf_*LU&MfzyW(o9Xm1)mCv&6 z-Riraq;M5oKqXyV+5!ZWyV+D1PF>^1`vnutC6glalC;u*M2h77XNy#yluQkeH;yXG z$3vE$L|=MI#QE)^N#>a@w&ZqMY zhMq;m74ect&Q<9I(fZf@KhIkDSebe64?*dCbzM6gxXPAP?TZ9= zUEc@^m+g&#Y9=Wi58VT>PW6uuO#0@T)PwzXV%;jD+d?B!YfTtTjmb$%cTdqIAP3uw zw$nN~Q0|ff3Z^gCCzn;9l~{Slamae7T6s>^LoByPC*%gbbGlu^>@45X@>6%mY3Wzw z^@8{2n}<>o`IA5OgP!HgKTKU|f}-wTySOY=s{&4FJwyADS&uHdGo@SfNBxI`7V$j7 zcrmOY`M_edq9ehriw$36cTIheIy)70s~=CYTM#oivIX%vRj=tpl>2uf*>+?A}(5iB7B(&L7_4TkJ>CNIfRUKa-VK zsdI3#U0jWPXoS>|hGrC#x^QcCvqQc3GSrD!!%ja23KlL> zO!NSbftnBNns1x)a&hS7&4HRfkwWXX?=-ipDia@iF25QQDY24BsQvAYrux|X!SboZ z4ANYRM^QDrf^PLFZRa$o(p!sQig?F65wScfE@@j6pe8!z1S<2Ubw`2+ge201b_zkJ zRL0+$c%1?_%Svi)k5BI!dfDofkv+36E_aLmDa$zfb<=9!-XyILXK!>J!;8*wKjJfX zL@CkSvu=cUdkI&^53?`y9LeC95(zgaK|YmQ7zJVTO)H6s#F`JGhwPX43`X8Llc8w2 z6o@{w3~CqsHO8R-nHZ^2*!Q*d)pPyUrha5A`*w%?0;&~ezl^Jw;ipvj*RUt1S; zDoP|B*$vFv#5xSDJ}h-$ zzFt`9$9J{jW@ARrU?J`nX$Wt<)2FtPPR+W_NGr#!U(afl>P%*zoH_w0TL!9%T&~v^ zVjfxR8_bGVX~OR}pY{S$B#M+b%VR=)3{Or(^?RQV#v zZ(fvjMLbjkpN@Apzdxyzn;*JV>H&_N@xd)sdjI5+xoeM5d;m)+r4Qc|(sDXwdg<`R zg?H+hw>=upHUJ^RkjLFjjUTjOy=(*ZxaQJpdT|f$t3#?-M4vAM;=1BJq20YBNj*Hd z%POT z)1FeaFUbG4QF!4Q?_F~%z@j4=_3S*#hxHiO2@sH7sP8RMlHW*^NMOM?=}R*poABy~y= zS}4&(6gd%!q_mNglw*<>eWO#I?~kwVxvuwpmg~On-|zQ4_w~GQ#+m>>9Zjev0026~ zRfIrA?>YBqs43p%4BjI}XDsvy7Ovw&3Pm(N2zW(s!a+EZMT-IhL0Uu{uMKnq02Kry zC|DRwA!F$r7LqoHL5f*i1sed|Jj7fYJsK3k!@(#98;6*vzlwk}B5;U}jubS7iwCzc zR!R8aI!QnfT@p=qi9mR`!`;MKg#Zf_(%@oN3|oK|;}G9;v5N8BG716z1`$T%5dS0< zOj!fRbNC?K5s9{?qn$8tCkG_P0qx@8Vgt8BW6&s!9SZGii$P-@ov~;P{Ch(vqVXdl zv4I5N@39m!9AcYL$i<>iB9RCwvPW|GQ7DXyiwg>EhqAM?RUm8yacm(?Y|9ob{h>er z1#~`xD`ark@Hs_VI44$!Lnt!+rvw)Frz~6WeVY^;h7!}bC=3!kSJDq4h4TNQEY?r7 zKo|)AoA3V=76ip{K~x|p;KcIjii3+>Iv0wI#q&X$ki!q+aAJP!;+kz7AxE%{!-eD5 zIU+IejSO}KMlg;^5bJaeRaI@Pm2m$Q-EctUW0BWpg)!fzo%1Y>Kukcplf@3usA31T zmXmlP8p<=X)>Cs1$|^}uE4P7Wd+Tr3_c9E5k+5TAVsOjvHN6GitNA_eFV=qP6y2V= zJvqd@Twl*H&os&ARx6>qmAIpwyH_7tIp0w-H5#U9v<{O2Gmz+7e;_9($0q4xRCsuJ z=+?76Q~OjyX2gDeH#*YOHKI@`6ramo6j%_$WR~XT<&8{F4DEMza3CzRv=klaRXM+D ze2BCkxv*W&$JjnnyXE@zm0KGVW?qbqjd^_Nh5f(~3p zE1 zZTCT^(rs7i`1tsBu(Il+8#lmRw0*nN4h^ajbAMKDu2K8Gefu){s&cy5)2bgCYN7Yh z%+B60vt`++zAgTUJ;wvg-P{g6x)O)?^73*Jz1i$fA|2~I;&E_iNo)3EzuDQ@=VN0` zK$?(G!|xt~VgOT@*yDT_9)P+nuvnLx5xpnNX!uTodh8;w?vxXH3>@hldr zcW{twAKB4$13Bfc3K87cbvYS<649SaGzCGYc#?4!Cr%3tZ+#$&`ljn);F-&cg0cD^$f=iXP6 zA)Gjm$cvrXub-q;RbpCob#+fXtQTcMR#a#VXNAmnRCV7S#Lxzok9l{TF;Cwm-@o%C zmg2n^@~Zh*mQwjtKJC8Ns!YB6TRb<2;ocX98$oc7`Ay1lBof&)Fcz)_Na>Hk*5A#p zv`!b905&6CNAU>xDWV1=dS-GMfh!+=`=nX;_sCzcKA;M`RdDA7<)F4i^|P))(7CJK zU-sInVJjD-0XKuYJ0>Cc zhSYJ7!bu^EWm@K^tVz)pK z{CXbLa$1%sLGI3e`4qng@%--TjZ-gsEE9D~D%C6sf#q>Foy=r1 zRgb`X7X1w)wmvpE7Y_`ctFEr@o8Ak(%b+-Uo&3bJHQe!a_RE$`^P=~S3;k0o7OH8> zKF|Ekn0VCS5IYu>nzSTyISOU8)Lvf5R9LkX^c}b?k(b|5W4?cVAD3prx9WaC?m__M zBD-Dp&V=BjI*X5AzKl(sUPdnTblv`1KUMoUb?O4^fzzG&;kW-Z=+JbI>8Eyinl+bb zD5GnZ25o|MDoLx!5r(>+Pg0I~q!6nmn+6X`EtAgoJNd={{XmrxRYj&I)sfB;S*(ge z^%75G9#De0U&}FlSjWR_tXr%#_w$?GIh>RXa$5`u#A`)7;|VY2Kr=gS^rhMDX`7?joD_n4i>LtVPP@#c}5`KCNCk; z3}dd$RIk5qCLuL5lcW_oa4>UewkoZ=j998(Cz>d(>r{s)|JL#42x7`Y;ppE)Rg;o2 z7X$t${zK7MhZeaEshg^rb9#revhwUx?y70IoT90x*GJv$*LslO)3o5LFXUay`I-5j zVy;%tpCl_w_d?BbnxB~JYSk((;@&ag<)ghby#lKZOI-M6oi_a(50GTUZ|>Q&b?Z<| z=UMx1$UQf`F74}Kf8^y2y4ZYHd;!nUm0!bnK-Pz%$K1RfkVU|*^c5?00~?Cwez=J~ L0fb6#YRZ2A>(}_r literal 0 HcmV?d00001 diff --git a/main/inc/ajax/exercise.ajax.php b/main/inc/ajax/exercise.ajax.php index cf1c3246d05..bceddb787ee 100755 --- a/main/inc/ajax/exercise.ajax.php +++ b/main/inc/ajax/exercise.ajax.php @@ -12,6 +12,7 @@ $action = $_REQUEST['a']; $course_id = api_get_course_int_id(); + if ($debug) { error_log("-----------------"); error_log("$action ajax call"); @@ -275,14 +276,14 @@ $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 @@ // 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 @@ // 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 @@ } // 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']; diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 0a5ce4c8a4c..4c0cb3c4451 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -485,6 +485,7 @@ 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 @@ 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 = "  ".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); } /** diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index 486e5773f3b..ed75708be94 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -98,7 +98,7 @@ public static function showQuestion( // 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 @@ public static function showQuestion( $header, ['style' => 'text-align:left;'] ); + } else if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ + echo ""; + $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 .= ''; + $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', ' '); + $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', ' '); + } + + $s .= Display::tag('tr', $header1); + + // add explanation + $header2 = Display::tag('th', ' '); + $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', + ' ', + ['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', ' '); + } + $s .= Display::tag('tr', $header2); } if ($show_comment) { @@ -276,10 +452,10 @@ public static function showQuestion( } $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="exercise-unique-answer-image col-xs-6 col-md-3" $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="exercise-unique-answer-image col-xs-6 col-md-3" $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 .= ''; $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="exercise-unique-answer-image col-xs-6 col-md-3" $s .= ''; } $s .= ''; + } 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 .= ''; + $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 .= ''; + } + $s.=''; } 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="exercise-unique-answer-image col-xs-6 col-md-3" break; case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE: $s .= ''; - $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="exercise-unique-answer-image col-xs-6 col-md-3" $s .= ''; $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="exercise-unique-answer-image col-xs-6 col-md-3" 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="exercise-unique-answer-image col-xs-6 col-md-3" $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="exercise-unique-answer-image col-xs-6 col-md-3" $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( '| / .*$|', @@ -722,8 +978,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" } } - // 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="exercise-unique-answer-image col-xs-6 col-md-3" ' '.$answer.' ' ); if (!empty($correctAnswerList) && !empty($studentAnswerList)) { - $answer = ''; + $answer = ""; $i = 0; foreach ($studentAnswerList as $studentItem) { // remove surronding brackets @@ -835,8 +1090,8 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" if (isset($select_items[$lines_count])) { $s .= '

'. - $select_items[$lines_count]['letter'].'.  '. - $select_items[$lines_count]['answer'].' + $select_items[$lines_count]['letter'].'.  '. + $select_items[$lines_count]['answer'].'

'; } else { @@ -854,7 +1109,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3"
"; $lines_count++; @@ -1074,6 +1329,7 @@ class="window window_left_question window{$questionId}_question"> UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE, + MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY ] )) { $s .= '
'; + $s .= $comment; + $s .= '
'; $s .= ''.$select_items[$lines_count]['letter'].'. '. - $select_items[$lines_count]['answer']; + $select_items[$lines_count]['answer']; $s .= "
'; @@ -1679,10 +1935,9 @@ public static function getLatestHotPotatoResult( * @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 @@ public static function get_exam_results_data( $courseCode = null, $showSessionField = false, $showExerciseCategories = false, - $userExtraFieldsToAdd = [], - $useCommaAsDecimalPoint = false + $userExtraFieldsToAdd = [] ) { //@todo replace all this globals global $documentPath, $filter; @@ -1711,12 +1965,7 @@ public static function get_exam_results_data( } $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 @@ public static function get_exam_results_data( 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 @@ public static function get_exam_results_data( } } - $scoreDisplay = new ScoreDisplay(); - $decimalSeparator = '.'; - $thousandSeparator = ','; - - if ($useCommaAsDecimalPoint) { - $decimalSeparator = ','; - $thousandSeparator = ''; - } - $listInfo = []; // Simple exercises if (empty($hotpotatoe_where)) { @@ -1977,6 +2219,7 @@ public static function get_exam_results_data( 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 @@ public static function get_exam_results_data( $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 @@ public static function get_exam_results_data( } $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 @@ public static function get_exam_results_data( // 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 @@ public static function get_exam_results_data( $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 = '
'; - if ($is_allowedToEdit) { if (isset($teacher_id_list)) { if (in_array( @@ -2190,7 +2428,7 @@ public static function get_exam_results_data( } // 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 @@ public static function get_exam_results_data( $filterByUser = isset($_GET['filter_by_user']) ? (int) $_GET['filter_by_user'] : 0; $delete_link = ''; + get_lang('DeleteAttempt'), + $results[$i]['username'], + $dt + ).'\')) return false;">'; $delete_link .= Display:: return_icon( 'delete.png', @@ -2235,9 +2473,6 @@ public static function get_exam_results_data( 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 @@ public static function get_exam_results_data( } 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 @@ public static function get_exam_results_data( 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 @@ public static function get_exam_results_data( 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 @@ public static function get_exam_results_data( * 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 @@ public static function show_score( $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 @@ public static function show_score( $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 @@ public static function show_score( */ public static function getModelStyle($model, $percentage) { + //$modelWithStyle = get_lang($model['name']); $modelWithStyle = '       '; + //$modelWithStyle .= $percentage; return $modelWithStyle; } @@ -3315,7 +3524,10 @@ public static function get_average_score_by_course($courseId, $session_id) $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 @@ public static function get_student_stats_by_question( * * @param int $question_id * @param int $exercise_id - * - * @return array + * @return int */ public static function getNumberStudentsFillBlanksAnswerCount( $question_id, @@ -3535,6 +3746,7 @@ public static function getNumberStudentsFillBlanksAnswerCount( ); $arrayCount = []; + foreach ($listFillTheBlankResult as $resultCount) { foreach ($resultCount as $index => $count) { //this is only for declare the array index per answer @@ -3997,6 +4209,41 @@ public static function get_number_students_finish_exercise( return $return; } + /** + * @param string $in_name is the name and the id of the + */ + public static function displayGroupMenu($in_name, $in_default, $in_onchange = "") + { + // check the default value of option + $tabSelected = [$in_default => " selected='selected' "]; + $res = ""; + $res .= ""; + return $res; + } + /** * @param int $exe_id */ @@ -4323,17 +4570,35 @@ public static function displayQuestionListByAttempt( } // end foreach() block that loops over all questions } - $total_score_text = null; + $totalScoreText = null; if ($show_results || $show_only_score) { - $total_score_text .= '
'; - $total_score_text .= self::getTotalScoreRibbon( - $objExercise, - $total_score, - $total_weight, - true, - $countPendingQuestions - ); - $total_score_text .= '
'; + if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + echo "

Vos Résultats


"; + } + $totalScoreText .= '
'; + 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 .= '
'; + } + + 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 @@ public static function displayQuestionListByAttempt( } if ($show_all_but_expected_answer) { - $exercise_content .= "
". - get_lang('ExerciseWithFeedbackWithoutCorrectionComment')."
"; + $exercise_content .= "
".get_lang('ExerciseWithFeedbackWithoutCorrectionComment')."
"; } // Remove audio auto play from questions on results page - refs BT#7939 @@ -4360,7 +4624,7 @@ public static function displayQuestionListByAttempt( $exercise_content ); - echo $total_score_text; + echo $totalScoreText; // Ofaj change BT#11784 if (!empty($objExercise->description)) { @@ -4370,7 +4634,7 @@ public static function displayQuestionListByAttempt( echo $exercise_content; if (!$show_only_score) { - echo $total_score_text; + echo $totalScoreText; } if (!empty($remainingMessage)) { @@ -4418,6 +4682,57 @@ public static function displayQuestionListByAttempt( } } + /** + * @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? '
' : ''; + + 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? '
' : ''; + } else { + $ribbon .= $displayChartDegree? '
' : ''; + } + + if ($displayChartDegree){ + $ribbon .= '

' . get_lang('YourTotalScore') . ": "; + + + $ribbon .= self::show_score($score, $weight, false, true); + $ribbon .= '

'; + $ribbon .= '
'; + } + + if ($checkPassPercentage) { + $ribbon .= self::showSuccessMessage( + $score, $weight, $objExercise->selectPassPercentage() + ); + } + + $ribbon .= $displayChartDegree? '
' : ''; + + return $ribbon; + } + + /** * @param Exercise $objExercise * @param float $score diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 6c42d74d6b2..820fc9ba509 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -496,6 +496,105 @@ public static function display_multiple_answer_true_false( echo ''; } + /** + * 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; + } + ?> + + + + + + + + + + + + + + + getColorResponse($studentChoice, + $answerCorrect, + $newOptions[$studentChoiceDegree]['position'] + ); + if($degreCertitudeColor == "#088A08" || $degreCertitudeColor == "#FE2E2E"){ + $color = "#FFFFFF"; + } else { + $color = "#000000"; + } + $codeResponse = $question->getCodeResponse($studentChoice, + $answerCorrect, + $newOptions[$studentChoiceDegree]['position'] + ); + + ?> + +
+ + + + ' . nl2br($answerComment) . ''; + } + ?> + + +   + + + %s
, 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 @@ $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.
Utilisez le bouton de retour en arrière de votre navigateur et recommencez"; @@ -2633,14 +2633,14 @@ $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 @@ $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 @@ $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 @@ $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,
+$HelloXAsYouCanSeeYourCourseListIsEmpty = "Bonjour %s, nous vous souhaitons la bienvenue,
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 @@ $EditExtraFieldOptions = "Modifier les options de champs"; $ExerciseDescriptionLabel = "Description"; $UserInactivedSinceX = "Utilisateur inactif depuis %s"; -$ContactInformationDescription = "Cher utilisateur,
-
-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.

-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.

-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.

+$ContactInformationDescription = "Cher utilisateur,
+
+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.

+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.

+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.

Veuillez prendre en considération que vous n'êtes pas obligé 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 @@ $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.
Cette activation n'est totalement réalisée que si le plugin PHP pour CKeditor WIRIS a été préalablement téléchargé et décompressé dans le répertoire de Chamilo main/inc/lib/javascript/ckeditor/plugins/.
+$EnabledWirisComment = "Activer l'éditeur mathématique WIRIS. En installant ce plugin, vous obtenez l'éditeur WIRIS et WIRIS CAS.
Cette activation n'est totalement réalisée que si le plugin PHP pour CKeditor WIRIS a été préalablement téléchargé et décompressé dans le répertoire de Chamilo main/inc/lib/javascript/ckeditor/plugins/.
Cela est nécessaire car Wiris est un logiciel propriétaire et ses services sont de nature commerciale. 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 @@ $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 en installer un ou vous adresser aux fournisseurs officiels de Chamilo 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 en installer un ou vous adresser aux fournisseurs officiels de Chamilo 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 localhost, une adresse IP (par exemple 192.168.13.54 ou un nom de domaine (par exemple my.video.com)."; @@ -6233,6 +6233,7 @@ $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 @@ $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 - félicitation"; +$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 @@ $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 @@ $ShibbolethMainActivateComment = "

Vous devez, en premier lieu, configurer Shibboleth pour votre serveur web. Pour le configurer pour Chamilo.

éditez le fichier main/auth/shibboleth/config/aai.class.php

Modifiez les valeurs de l'objet $result avec les nom des attributs retourné par votre serveur Shibboleth.

Les valeurs à modifier sont
  • $result->unique_id = 'mail';
  • $result->firstname = 'cn';
  • $result->lastname = 'uid';
  • $result->email = 'mail';
  • $result->language = '-';
  • $result->gender = '-';
  • $result->address = '-';
  • $result->staff_category = '-';
  • $result->home_organization_type = '-';
  • $result->home_organization = '-';
  • $result->affiliation = '-';
  • $result->persistent_id = '-';
  • ...

Vous trouverez dans les Plugin un bouton 'Login Shibboleth', paramétrable, qui s'ajoutera sur la page d'accueil de votre campus Chamilo."; $LdapDescriptionTitle = "Identification LDAP"; $FacebookMainActivateTitle = "

Configuration de l'authentification via Facebook

"; -$FacebookMainActivateComment = "

Créez votre application Facebook
Vous devez, d'abord, créer une application Facebook (cf. https://developers.facebook.com/apps) avec votre compte Facebook.
-
Éditez le fichier app/config/configuration.php
Et décommentez la ligne $_configuration['facebook_auth'] = 1;
-
Éditez le fichier app/config/auth.conf.php
Entrez les valeurs 'appId' et 'secret', fournies par Facebook, pour la variable $facebook_config.
-
Éditez le fichier main/inc/conf/auth.conf.php
Et décommentez les lignes $facebook_config
+$FacebookMainActivateComment = "

Créez votre application Facebook
Vous devez, d'abord, créer une application Facebook (cf. https://developers.facebook.com/apps) avec votre compte Facebook.
+
Éditez le fichier app/config/configuration.php
Et décommentez la ligne $_configuration['facebook_auth'] = 1;
+
Éditez le fichier app/config/auth.conf.php
Entrez les valeurs 'appId' et 'secret', fournies par Facebook, pour la variable $facebook_config.
+
Éditez le fichier main/inc/conf/auth.conf.php
Et décommentez les lignes $facebook_config
Activez le plugin Facebook de Chamilo
Et placez-le dans la région login_top ou login_bottom.
Vous pouvez changer l'image de connexion dans les options de configuration du plugin.

"; $AnnouncementForGroup = "Annonce pour un groupe"; $AllGroups = "Tous les groupes"; @@ -7435,7 +7462,7 @@ $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,
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.
Cordialement,
+$MailCronCourseFinishedBody = "Cher/Chère %s,
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.
Cordialement,
%s"; $GenerateDefaultContent = "Générer du contenu par défaut"; $ThanksForYourSubscription = "Merci pour votre inscription"; @@ -7817,7 +7844,7 @@ $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.
+$UserXHasBeenAssignedToBossWithUrlX = "Vous avez été assigné comme tuteur pour l'apprenant %s.
Vous pouvez accéder à sa fiche ici: %s"; $ShortName = "Nom court"; $Portal = "Portail"; @@ -7973,13 +8000,13 @@ $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 @@ $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 \"" + . "%exerTitle" //$objExercise->title + . "\"." + . "
Pour consulter le détail des résultats " + . "

1. Connectez vous sur la plate forme Chamilo (identifiant/mot de passe universitaire) : " + . "se connecter à Chamilo : " + . "

2. Puis cliquez sur ce lien %s " + . "voir mes résultats détaillés .

"; +$KindRegards = "Cordialement,
"; +$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"; From 34ed68e3ac9818f502941e239353633e95e0806b Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:17:48 +0200 Subject: [PATCH 02/30] Update multiple_answer_true_false_degree_certainty.class.php --- .../multiple_answer_true_false_degree_certainty.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/exercise/multiple_answer_true_false_degree_certainty.class.php b/main/exercise/multiple_answer_true_false_degree_certainty.class.php index 4215a3b8a0d..5161c0e3e94 100644 --- a/main/exercise/multiple_answer_true_false_degree_certainty.class.php +++ b/main/exercise/multiple_answer_true_false_degree_certainty.class.php @@ -27,7 +27,7 @@ class MultipleAnswerTrueFalseDegreeCertainty extends Question { /** * Constructor */ - public function MultipleAnswerTrueFalseDegreeCertainty() { + public function __construct() { parent::__construct(); $this->type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY; $this->isContent = $this->getIsContent(); From 5907ef4480d6fe1b7016208328ccd0d3e7f85dce Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:19:15 +0200 Subject: [PATCH 03/30] Update exercise.lib.php --- main/inc/lib/exercise.lib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index ed75708be94..53171dc1a61 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -411,11 +411,13 @@ function handleRadioRow(event, question_id, answer_id) { ' ', ['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;' ; + $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)); + array('style' => 'background-color: #EFEFFC; color: black; width: 110px; text-align:center; + vertical-align: top; padding:5px; '.$color_border2)); $counter2++; } From e7e20724c7514dc67bcdf50e447ebdae58e8ddd5 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:22:02 +0200 Subject: [PATCH 04/30] Rename multiple_answer_true_false_degree_certainty.class.php to multipleAnswerTrueFalseDegreeCertainty.php --- ...ainty.class.php => multipleAnswerTrueFalseDegreeCertainty.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename main/exercise/{multiple_answer_true_false_degree_certainty.class.php => multipleAnswerTrueFalseDegreeCertainty.php} (100%) diff --git a/main/exercise/multiple_answer_true_false_degree_certainty.class.php b/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php similarity index 100% rename from main/exercise/multiple_answer_true_false_degree_certainty.class.php rename to main/exercise/multipleAnswerTrueFalseDegreeCertainty.php From 3d663b2e6f31b2a6b632793d3623335c3d138410 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:23:20 +0200 Subject: [PATCH 05/30] Update question.class.php --- main/exercise/question.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/exercise/question.class.php b/main/exercise/question.class.php index ea8a37046a0..a9e6339fbf8 100755 --- a/main/exercise/question.class.php +++ b/main/exercise/question.class.php @@ -51,7 +51,7 @@ abstract class Question 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.php', 'MultipleAnswerTrueFalseDegreeCertainty' ], MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE => [ From 8feed6a58c2f927e76d769092c739e65b930a02a Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:24:44 +0200 Subject: [PATCH 06/30] Update exercise_submit.php --- main/exercise/exercise_submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/exercise/exercise_submit.php b/main/exercise/exercise_submit.php index 232d25f1015..330ef07c5d7 100755 --- a/main/exercise/exercise_submit.php +++ b/main/exercise/exercise_submit.php @@ -823,7 +823,7 @@ // show histogram require_once api_get_path(SYS_CODE_PATH) - . "exercise/multiple_answer_true_false_degree_certainty.class.php"; + . "exercise/multipleAnswerTrueFalseDegreeCertainty.php"; $message .= MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults($exe_id, $objExercise); $message .= get_lang('KindRegards'); From 8bdd8fadc0981e2b5ec9ecbdef97f4a1a7aa702c Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:38:29 +0200 Subject: [PATCH 07/30] Update api.lib.php --- main/inc/lib/api.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 4c0cb3c4451..d070347c9d8 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -749,7 +749,7 @@ function api_get_path($path = '', $configuration = []) $server_name .= ":".$_SERVER['SERVER_PORT']; } $root_web = $server_protocol.'://'.$server_name.$root_rel; - $root_sys = str_replace('\\', '/', realpath(__DIR__ . '/../../ficher test degre certitudes/')).'/'; + $root_sys = str_replace('\\', '/', realpath(__DIR__.'/../../../')).'/'; } // Here we give up, so we don't touch anything. } From 53d13e2b682bd97a3b85747c12516c2034608724 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:40:32 +0200 Subject: [PATCH 08/30] Update exercise_show_functions.lib.php --- main/inc/lib/exercise_show_functions.lib.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 820fc9ba509..8af96e0ea4d 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -511,8 +511,15 @@ public static function display_multiple_answer_true_false( * @param boolean $inResultsDisabled * @return void */ - static function displayMultipleAnswerTrueFalseDegreeCertainty( - $feedbackType, $studentChoice, $studentChoiceDegree, $answer, $answerComment, $answerCorrect, $id, $questionId, $answerNumber, $inResultsDisabled + static function displayMultipleAnswerTrueFalseDegreeCertainty ( + $feedbackType, + $studentChoice, + $studentChoiceDegree, + $answer, + $answerComment, + $answerCorrect, + $questionId, + $inResultsDisabled ) { $hideExpectedAnswer = false; From b730333397a17f504c593fc383d2d853d98ceaa8 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:42:23 +0200 Subject: [PATCH 09/30] Update exercise.class.php --- main/exercise/exercise.class.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index 23e6e34c0ab..5399640243e 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -4678,9 +4678,7 @@ public function manage_answer( $answer, $answerComment, $answerCorrect, - 0, $questionId, - 0, $results_disabled ); @@ -5074,9 +5072,7 @@ public function manage_answer( $answer, $answerComment, $answerCorrect, - $exeId, $questionId, - $answerId, $results_disabled ); } else { @@ -5087,9 +5083,7 @@ public function manage_answer( $answer, $answerComment, $answerCorrect, - $exeId, $questionId, - "", $results_disabled ); } From 2e30bfd74100717381f2b0563a937ed53c54764b Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:44:14 +0200 Subject: [PATCH 10/30] Update exercise.class.php --- main/exercise/exercise.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index 5399640243e..5542de88a04 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -3597,7 +3597,8 @@ public function manage_answer( } $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; - $studentChoiceDegree = isset($choiceDegreeCertainty[$answerAutoId]) ? $choiceDegreeCertainty[$answerAutoId] : null; + $studentChoiceDegree = isset($choiceDegreeCertainty[$answerAutoId]) ? + $choiceDegreeCertainty[$answerAutoId] : null; // student score update if (!empty($studentChoice)){ From bc1499fa67594537b64b068f52a50a1a2cab963e Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:46:15 +0200 Subject: [PATCH 11/30] Update exercise.lib.php --- main/inc/lib/exercise.lib.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index 53171dc1a61..3e5be8c5f0f 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -687,7 +687,9 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" } $attributes['onChange'] = 'RadioValidator(' . $questionId . ', ' . $numAnswer . ')'; // gère la séletion des radio button du degré de certitude - if (isset($myChoiceDegreeCertainty[$numAnswer]) && $id == $myChoiceDegreeCertainty[$numAnswer]) { + if (isset($myChoiceDegreeCertainty[$numAnswer]) && + $id == $myChoiceDegreeCertainty[$numAnswer] + ) { $attributes1 = ['checked' => 1, 'selected' => 1]; } else { $attributes1 = []; From 822753fd9b4af58776bee9734a1f01fc46cc28ce Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:47:48 +0200 Subject: [PATCH 12/30] Update exercise_show_functions.lib.php --- main/inc/lib/exercise_show_functions.lib.php | 43 ++++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 8af96e0ea4d..5179635c11b 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -567,33 +567,32 @@ static function displayMultipleAnswerTrueFalseDegreeCertainty ( getColorResponse($studentChoice, - $answerCorrect, - $newOptions[$studentChoiceDegree]['position'] - ); - if($degreCertitudeColor == "#088A08" || $degreCertitudeColor == "#FE2E2E"){ - $color = "#FFFFFF"; - } else { - $color = "#000000"; - } - $codeResponse = $question->getCodeResponse($studentChoice, - $answerCorrect, - $newOptions[$studentChoiceDegree]['position'] - ); - + $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'] + ); ?>
- - ' . nl2br($answerComment) . ''; - } - ?> - + + ' . nl2br($answerComment) . ''; + } + ?> +   From cb887d30122d7dd9ce03cf4f7c5d84a975679cae Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:50:43 +0200 Subject: [PATCH 13/30] Update exercise.lib.php --- main/inc/lib/exercise.lib.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index 3e5be8c5f0f..ca411e5d33c 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -712,7 +712,9 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $attributes ), ['style' => 'text-align:center; background-color:#F7E1D7;', - 'onclick' => 'handleRadioRow(event, ' . $questionId . ', ' . $numAnswer . ')' + 'onclick' => 'handleRadioRow(event, ' . + $questionId . ', ' . + $numAnswer . ')' ] ); } else { @@ -723,7 +725,9 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $attributes1 ), ['style' => 'text-align:center; background-color:#EFEFFC;', - 'onclick' => 'handleRadioRow(event, ' . $questionId . ', ' . $numAnswer . ')' + 'onclick' => 'handleRadioRow(event, ' . + $questionId . ', ' . + $numAnswer . ')' ] ); } From 18e09f7e32356670b25acda70bae88f72c1068f3 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:51:52 +0200 Subject: [PATCH 14/30] Update exercise_show_functions.lib.php --- main/inc/lib/exercise_show_functions.lib.php | 42 ++++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 5179635c11b..79b034709e1 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -530,31 +530,31 @@ static function displayMultipleAnswerTrueFalseDegreeCertainty ( @@ -562,7 +562,7 @@ static function displayMultipleAnswerTrueFalseDegreeCertainty ( @@ -587,10 +587,10 @@ static function displayMultipleAnswerTrueFalseDegreeCertainty ( ' . nl2br($answerComment) . ''; - } + $color = "black"; + if (isset($newOptions[$studentChoice])) { + echo '' . nl2br($answerComment) . ''; + } ?> From 4bd3ff6163f1fb13f1b34802fe727053f534fb2a Mon Sep 17 00:00:00 2001 From: pielRouge Date: Wed, 11 Jul 2018 15:52:44 +0200 Subject: [PATCH 15/30] Update exercise.lib.php --- main/inc/lib/exercise.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index ca411e5d33c..5e212057d6f 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -947,7 +947,8 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $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( '/\[[^]]+\]/', From 7176820edcc3b5d8a93055231b7960ba5196b041 Mon Sep 17 00:00:00 2001 From: Hubert Borderiou Date: Wed, 11 Jul 2018 16:25:56 +0200 Subject: [PATCH 16/30] Patch https://flintci.io/repositories/1013/analyses/8726 --- main/exercise/exercise.class.php | 27 +- main/exercise/exercise_show.php | 9 +- main/exercise/exercise_submit.php | 25 +- ...multipleAnswerTrueFalseDegreeCertainty.php | 2048 +++++++++-------- main/exercise/question.class.php | 4 +- main/inc/lib/api.lib.php | 4 +- main/inc/lib/exercise.lib.php | 110 +- main/inc/lib/exercise_show_functions.lib.php | 84 +- 8 files changed, 1174 insertions(+), 1137 deletions(-) diff --git a/main/exercise/exercise.class.php b/main/exercise/exercise.class.php index 5542de88a04..138e6482182 100755 --- a/main/exercise/exercise.class.php +++ b/main/exercise/exercise.class.php @@ -3398,7 +3398,7 @@ public function manage_answer( // Extra information of the question if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || - $answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY && + $answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY && !empty($extra) ) { $extra = explode(':', $extra); @@ -3582,7 +3582,7 @@ public function manage_answer( $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT WHERE - exe_id = $exeId AND question_id = " . $questionId; + exe_id = $exeId AND question_id = ".$questionId; $result = Database::query($sql); while ($row = Database::fetch_array($result)) { @@ -3597,12 +3597,11 @@ public function manage_answer( } $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null; - $studentChoiceDegree = isset($choiceDegreeCertainty[$answerAutoId]) ? + $studentChoiceDegree = isset($choiceDegreeCertainty[$answerAutoId]) ? $choiceDegreeCertainty[$answerAutoId] : null; // student score update - if (!empty($studentChoice)){ - + if (!empty($studentChoice)) { if ($studentChoice == $answerCorrect) { // correct answer and student is Unsure or PrettySur if ($quiz_question_options[$studentChoiceDegree]['position'] >= 3 @@ -3869,7 +3868,7 @@ public function manage_answer( // 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 .= '' . $user_tags[$i] . ''; + $answer .= ''.$user_tags[$i].''; } else { // adds a tabulation if no word has been typed by the student $answer .= ''; // remove   that causes issue @@ -4133,7 +4132,7 @@ public function manage_answer( // 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 .= '' . $userTags[$i] . ''; + $answer .= ''.$userTags[$i].''; $calculatedChoice = $userTags[$i]; } else { // adds a tabulation if no word has been typed by the student @@ -4670,8 +4669,7 @@ public function manage_answer( $results_disabled, $showTotalScoreAndUserChoicesInLastAttempt ); - } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ - + } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( $feedback_type, $studentChoice, @@ -4682,7 +4680,6 @@ public function manage_answer( $questionId, $results_disabled ); - } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) { ExerciseShowFunctions::display_multiple_answer_combination_true_false( $this, @@ -5064,7 +5061,7 @@ public function manage_answer( ); } break; - case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY : + case MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY: if ($answerId == 1) { ExerciseShowFunctions::displayMultipleAnswerTrueFalseDegreeCertainty( $feedback_type, @@ -5648,7 +5645,7 @@ public function manage_answer( $answerDegreeCertainty = $replyDegreeCertainty[$i]; Event::saveQuestionAttempt( $questionScore, - $answerChoosen . ':' . $choice[$answerChoosen] . ':' . $choiceDegreeCertainty[$answerDegreeCertainty], + $answerChoosen.':'.$choice[$answerChoosen].':'.$choiceDegreeCertainty[$answerDegreeCertainty], $quesId, $exeId, $i, @@ -5753,7 +5750,7 @@ public function manage_answer( ) { $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])) { @@ -5795,8 +5792,8 @@ public function manage_answer( if ($saved_results) { $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; + exe_result = exe_result + '.floatval($questionScore).' + WHERE exe_id = '.$exeId; Database::query($sql); } diff --git a/main/exercise/exercise_show.php b/main/exercise/exercise_show.php index b779c36bc63..397b1434bb8 100755 --- a/main/exercise/exercise_show.php +++ b/main/exercise/exercise_show.php @@ -781,7 +781,6 @@ function getFCK(vals, marksid) { $feedback_form->setDefaults($default); $feedback_form->display(); - echo '
'; if ($allowRecordAudio && $allowTeacherCommentAudio) { @@ -966,7 +965,7 @@ function getFCK(vals, marksid) { $totalWeighting, true ); - } else{ + } else { $totalScoreText .= ExerciseLib::getTotalScoreRibbon( $objExercise, $myTotalScoreTemp, @@ -979,7 +978,7 @@ function getFCK(vals, marksid) { $totalScoreText .= '
'; } } -if ( $answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ +if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { $chartMultiAnswer = MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults($id, $objExercise); echo $chartMultiAnswer; } @@ -1130,14 +1129,14 @@ function getFCK(vals, marksid) { + ?> title . "\""); + $subject = "[".get_lang('DoNotReply')."] " + .html_entity_decode(get_lang('ResultAccomplishedTest')." \"".$objExercise->title."\""); // message sended to the student - $message = get_lang('Dear') . ' ' . $recipient_name . ",

"; + $message = get_lang('Dear').' '.$recipient_name.",

"; //calcul du chemmin sans les script php $url = $_SERVER['SCRIPT_NAME']; $pos = strripos($url, "/"); @@ -813,9 +813,9 @@ $path = substr($url, 0, $pos); $message .= get_lang('MessageQuestionCertainty'); - $exerciseLink = ""; + $exerciseLink = ""; $titleExercice = $objExercise->title; $message = str_replace('%exerTitle', $titleExercice, $message); $message = str_replace('%webPath', api_get_path(WEB_PATH), $message); @@ -823,7 +823,7 @@ // show histogram require_once api_get_path(SYS_CODE_PATH) - . "exercise/multipleAnswerTrueFalseDegreeCertainty.php"; + ."exercise/multipleAnswerTrueFalseDegreeCertainty.php"; $message .= MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults($exe_id, $objExercise); $message .= get_lang('KindRegards'); @@ -837,12 +837,11 @@ ['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" + .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; } @@ -1098,8 +1097,6 @@ $onsubmit = "onsubmit=\"return validateFlashVar('".$number_of_hotspot_questions."', '".get_lang('HotspotValidateError1')."', '".get_lang('HotspotValidateError2')."');\""; } - - $saveIcon = Display::return_icon( 'save.png', get_lang('Saved'), diff --git a/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php b/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php index 5161c0e3e94..6b388880121 100644 --- a/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php +++ b/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php @@ -1,403 +1,433 @@ -type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY; - $this->isContent = $this->getIsContent(); - $this->optionsTitle = [1 => 'langAnswers', 2 => 'DegreeOfCertainty']; - $this->options = [ - 1 => 'True', - 2 => 'False', - 3 => '50%', - 4 => '60%', - 5 => '70%', - 6 => '80%', - 7 => '90%', - 8 => '100%' - ]; - } - - /** - * function which redefines Question::createAnswersForm - * @param FormValidator $form - */ - public function createAnswersForm($form) { - $nbAnswers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4; - // The previous default value was 2. See task #1759. - $nbAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); - - $courseId = api_get_course_int_id(); - $objEx = $_SESSION['objExercise']; - $renderer = & $form->defaultRenderer(); - $defaults = []; - - $html = ''; - - // show column comment when feedback is enable - if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { - $html .=''; - } - $html .= ''; - $form->addElement('label', get_lang('Answers') . '
', $html); - - $correct = 0; - $answer = null; - if (!empty($this->id)) { - $answer = new Answer($this->id); - $answer->read(); - if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) { - $nbAnswers = $answer->nbrAnswers; - } - } - - $form->addElement('hidden', 'nb_answers'); - $boxesNames = []; - - if ($nbAnswers < 1) { - $nbAnswers = 1; - Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer')); - } - - // Can be more options - $optionData = Question::readQuestionOption($this->id, $courseId); - - - for ($i = 1; $i <= $nbAnswers; ++$i) { - - $renderer->setElementTemplate( - '', - 'correct[' . $i . ']' - ); - $renderer->setElementTemplate( - '', - 'counter[' . $i . ']' - ); - $renderer->setElementTemplate( - '', - 'answer[' . $i . ']' - ); - $renderer->setElementTemplate( - '', - 'comment[' . $i . ']' - ); - - $answerNumber = $form->addElement('text', 'counter[' . $i . ']', null, 'value="' . $i . '"'); - $answerNumber->freeze(); - - if (is_object($answer)) { - $defaults['answer[' . $i . ']'] = $answer->answer[$i]; - $defaults['comment[' . $i . ']'] = $answer->comment[$i]; - $defaults['weighting[' . $i . ']'] = float_format($answer->weighting[$i], 1); - - $correct = $answer->correct[$i]; - $defaults['correct[' . $i . ']'] = $correct; - - $j = 1; - if (!empty($optionData)) { - foreach ($optionData as $id => $data) { - $form->addElement('radio', 'correct[' . $i . ']', null, null, $id); - $j++; - if ($j == 3) { - break; - } - } - } - } else { - $form->addElement('radio', 'correct[' . $i . ']', null, null, 1); - $form->addElement('radio', 'correct[' . $i . ']', null, null, 2); - - $defaults['answer[' . $i . ']'] = ''; - $defaults['comment[' . $i . ']'] = ''; - $defaults['correct[' . $i . ']'] = ''; - } - - $boxesNames[] = 'correct[' . $i . ']'; - $form->addElement( - 'html_editor', - 'answer[' . $i . ']', - null, - 'style="vertical-align:middle"', - array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100')); - $form->addRule('answer[' . $i . ']', get_lang('ThisFieldIsRequired'), 'required'); - - // show comment when feedback is enable - if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { - $form->addElement('html_editor', - 'comment[' . $i . ']', - null, - 'style="vertical-align:middle"', - array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100')); - } - $form->addElement('html', ''); - } - - $form->addElement('html', '
' - . get_lang('Number') - . '' - . get_lang('True') - . '' - . get_lang('False') - . '' - . get_lang('Answer') - . '' . get_lang('Comment') . '
{error}
{element}
{error}
{element}
{error}
{element}
{error}
{element}
'); - $form->addElement('html', '
'); - - // 3 scores - $form->addElement('text', 'option[1]', get_lang('Correct'), array('class' => 'span1', 'value' => '1')); - $form->addElement('text', 'option[2]', get_lang('Wrong'), array('class' => 'span1', 'value' => '-0.5')); - - $form->addElement('hidden', 'option[3]', 0); - - $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required'); - $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required'); - - $form->addElement('html', ''); - $form->addElement('hidden', 'options_count', 3); - $form->addElement('html', '


'); - - //Extra values True, false, Dont known - if (!empty($this->extra)) { - $scores = explode(':', $this->extra); - if (!empty($scores)) { - for ($i = 1; $i <= 3; $i++) { - $defaults['option[' . $i . ']'] = $scores[$i - 1]; - } - } - } - - global $text, $class; - if ($objEx->edit_exercise_in_lp == true) { - - $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"'); - $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"'); - $form->addElement('submit', 'submitQuestion', $text, 'class="' . $class . '"'); - - } - $renderer->setElementTemplate('{element} ', 'lessAnswers'); - $renderer->setElementTemplate('{element} ', 'submitQuestion'); - $renderer->setElementTemplate('{element} ', 'moreAnswers'); - $form->addElement('html', ''); - $defaults['correct'] = $correct; - - if (!empty($this->id)) { - $form->setDefaults($defaults); - } else { - //if ($this -> isContent == 1) { - $form->setDefaults($defaults); - //} - } - $form->setConstants(['nb_answers' => $nbAnswers]); - } - - /** - * abstract function which creates the form to create / edit the answers of the question - * @param FormValidator $form - * @param Exercise $exercise - */ - public function processAnswersCreation($form, $exercise) { - $questionWeighting = $nbrGoodAnswers = 0; - $objAnswer = new Answer($this->id); - $nbAnswers = $form->getSubmitValue('nb_answers'); - - $courseId = api_get_course_int_id(); - - $correct = []; - $options = Question::readQuestionOption($this->id, $courseId); - - - if (!empty($options)) { - foreach ($options as $optionData) { - $id = $optionData['id']; - unset($optionData['id']); - Question::updateQuestionOption($id, $optionData, $courseId); - } - } else { - for ($i = 1; $i <= 8; $i++) { - $lastId = Question::saveQuestionOption($this->id, $this->options[$i], $courseId, $i); - $correct[$i] = $lastId; - } - } - - /* Getting quiz_question_options (true, false, doubt) because - it's possible that there are more options in the future */ - - $newOptions = Question::readQuestionOption($this->id, $courseId); - - $sortedByPosition = []; - foreach ($newOptions as $item) { - $sortedByPosition[$item['position']] = $item; - } - - /* Saving quiz_question.extra values that has the correct scores of - the true, false, doubt options registered in this format - XX:YY:ZZZ where XX is a float score value. */ - $extraValues = []; - - for ($i = 1; $i <= 3; $i++) { - $score = trim($form->getSubmitValue('option[' . $i . ']')); - $extraValues[] = $score; - } - $this->setExtra(implode(':', $extraValues)); - - for ($i = 1; $i <= $nbAnswers; $i++) { - $answer = trim($form->getSubmitValue('answer[' . $i . ']')); - $comment = trim($form->getSubmitValue('comment[' . $i . ']')); - $goodAnswer = trim($form->getSubmitValue('correct[' . $i . ']')); - if (empty($options)) { - //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered - $goodAnswer = $sortedByPosition[$goodAnswer]['id']; - } - $questionWeighting += $extraValues[0]; //By default 0 has the correct answers - $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i); - } - - // saves the answers into the data base - $objAnswer->save(); - - // sets the total weighting of the question - $this->updateWeighting($questionWeighting); - $this->save($exercise); - } - - /** - * @param int $feedbackType - * @param int $counter - * @param float $score - * @return null|string - */ - function return_header($feedbackType = null, $counter = null, $score = null) { - $header = parent::return_header($feedbackType, $counter, $score); - $header .= '' - ; - if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { - $header .= ''; - } else { - $header .= ''; - } - $header .= ''; - return $header; - } - - /** - * Method to recovery color to show by precision of the student's answer - * @param $studentAnwser - * @param $expectedAnswer - * @param $studentDegreeChoicePosition - * @return string - */ - function getColorResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) { - $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; - if ($checkResult) { - if ($studentDegreeChoicePosition >= 6) - return '#088A08'; - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) - return '#A9F5A9'; - if ($studentDegreeChoicePosition == 3) - return '#FFFFFF'; - } else { - if ($studentDegreeChoicePosition >= 6) - return '#FE2E2E'; - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) - return '#F6CECE'; - if ($studentDegreeChoicePosition == 3) - return '#FFFFFF'; - } - } - - /** - * Return the color code for student answer - * @param $studentAnwser - * @param $expectedAnswer - * @param $studentDegreeChoicePosition - * @return int - */ - function getStatusResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) { - $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; - if ($checkResult) { - if ($studentDegreeChoicePosition >= 6) - return self::LEVEL_DARKGREEN; - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) - return self::LEVEL_LIGHTGREEN; - if ($studentDegreeChoicePosition == 3) - return self::LEVEL_WHITE; - } else { - if ($studentDegreeChoicePosition >= 6) - return self::LEVEL_DARKRED; - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) - return self::LEVEL_LIGHTRED; - if ($studentDegreeChoicePosition == 3) - return self::LEVEL_WHITE; - } - } - - /** - * Method to recovery lable for codes colors - * @param $studentAnwser - * @param $expectedAnswer - * @param $studentDegreeChoicePosition - * @return string - */ - public function getCodeResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) { - $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; - if ($checkResult) { - if ($studentDegreeChoicePosition >= 6) - return get_lang('langVerySure'); - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) - return get_lang('langPrettySur'); - if ($studentDegreeChoicePosition == 3) - return get_lang('langIgnorance'); - } else { - if ($studentDegreeChoicePosition >= 6) - return get_lang('langVeryUnsure'); - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) - return get_lang('langUnsure'); - if ($studentDegreeChoicePosition == 3) - return get_lang('langIgnorance'); - } - - } - - /** - * Method to show the code color and his meaning for the test result - */ - public static function showColorCode() { +type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY; + $this->isContent = $this->getIsContent(); + $this->optionsTitle = [1 => 'langAnswers', 2 => 'DegreeOfCertainty']; + $this->options = [ + 1 => 'True', + 2 => 'False', + 3 => '50%', + 4 => '60%', + 5 => '70%', + 6 => '80%', + 7 => '90%', + 8 => '100%', + ]; + } + + /** + * function which redefines Question::createAnswersForm. + * + * @param FormValidator $form + */ + public function createAnswersForm($form) + { + $nbAnswers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4; + // The previous default value was 2. See task #1759. + $nbAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); + + $courseId = api_get_course_int_id(); + $objEx = $_SESSION['objExercise']; + $renderer = &$form->defaultRenderer(); + $defaults = []; + + $html = '
' - . get_lang("Choice") - . '' - . get_lang("ExpectedChoice") - . '' - . get_lang("Answer") - . '' - . get_lang("YourDegreeOfCertainty") - . ' ' . get_lang("Comment") . ' 
'; + + // show column comment when feedback is enable + if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + $html .= ''; + } + $html .= ''; + $form->addElement('label', get_lang('Answers').'
', $html); + + $correct = 0; + $answer = null; + if (!empty($this->id)) { + $answer = new Answer($this->id); + $answer->read(); + if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) { + $nbAnswers = $answer->nbrAnswers; + } + } + + $form->addElement('hidden', 'nb_answers'); + $boxesNames = []; + + if ($nbAnswers < 1) { + $nbAnswers = 1; + Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer')); + } + + // Can be more options + $optionData = Question::readQuestionOption($this->id, $courseId); + + for ($i = 1; $i <= $nbAnswers; ++$i) { + $renderer->setElementTemplate( + '', + 'correct['.$i.']' + ); + $renderer->setElementTemplate( + '', + 'counter['.$i.']' + ); + $renderer->setElementTemplate( + '', + 'answer['.$i.']' + ); + $renderer->setElementTemplate( + '', + 'comment['.$i.']' + ); + + $answerNumber = $form->addElement('text', 'counter['.$i.']', null, 'value="'.$i.'"'); + $answerNumber->freeze(); + + if (is_object($answer)) { + $defaults['answer['.$i.']'] = $answer->answer[$i]; + $defaults['comment['.$i.']'] = $answer->comment[$i]; + $defaults['weighting['.$i.']'] = float_format($answer->weighting[$i], 1); + + $correct = $answer->correct[$i]; + $defaults['correct['.$i.']'] = $correct; + + $j = 1; + if (!empty($optionData)) { + foreach ($optionData as $id => $data) { + $form->addElement('radio', 'correct['.$i.']', null, null, $id); + $j++; + if ($j == 3) { + break; + } + } + } + } else { + $form->addElement('radio', 'correct['.$i.']', null, null, 1); + $form->addElement('radio', 'correct['.$i.']', null, null, 2); + + $defaults['answer['.$i.']'] = ''; + $defaults['comment['.$i.']'] = ''; + $defaults['correct['.$i.']'] = ''; + } + + $boxesNames[] = 'correct['.$i.']'; + $form->addElement( + 'html_editor', + 'answer['.$i.']', + null, + 'style="vertical-align:middle"', + ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']); + $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required'); + + // show comment when feedback is enable + if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + $form->addElement('html_editor', + 'comment['.$i.']', + null, + 'style="vertical-align:middle"', + ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']); + } + $form->addElement('html', ''); + } + + $form->addElement('html', '
' + .get_lang('Number') + .'' + .get_lang('True') + .'' + .get_lang('False') + .'' + .get_lang('Answer') + .''.get_lang('Comment').'
{error}
{element}
{error}
{element}
{error}
{element}
{error}
{element}
'); + $form->addElement('html', '
'); + + // 3 scores + $form->addElement('text', 'option[1]', get_lang('Correct'), ['class' => 'span1', 'value' => '1']); + $form->addElement('text', 'option[2]', get_lang('Wrong'), ['class' => 'span1', 'value' => '-0.5']); + + $form->addElement('hidden', 'option[3]', 0); + + $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required'); + $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required'); + + $form->addElement('html', ''); + $form->addElement('hidden', 'options_count', 3); + $form->addElement('html', '


'); + + //Extra values True, false, Dont known + if (!empty($this->extra)) { + $scores = explode(':', $this->extra); + if (!empty($scores)) { + for ($i = 1; $i <= 3; $i++) { + $defaults['option['.$i.']'] = $scores[$i - 1]; + } + } + } + + global $text, $class; + if ($objEx->edit_exercise_in_lp == true) { + $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"'); + $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"'); + $form->addElement('submit', 'submitQuestion', $text, 'class="'.$class.'"'); + } + $renderer->setElementTemplate('{element} ', 'lessAnswers'); + $renderer->setElementTemplate('{element} ', 'submitQuestion'); + $renderer->setElementTemplate('{element} ', 'moreAnswers'); + $form->addElement('html', ''); + $defaults['correct'] = $correct; + + if (!empty($this->id)) { + $form->setDefaults($defaults); + } else { + //if ($this -> isContent == 1) { + $form->setDefaults($defaults); + //} + } + $form->setConstants(['nb_answers' => $nbAnswers]); + } + + /** + * abstract function which creates the form to create / edit the answers of the question. + * + * @param FormValidator $form + * @param Exercise $exercise + */ + public function processAnswersCreation($form, $exercise) + { + $questionWeighting = $nbrGoodAnswers = 0; + $objAnswer = new Answer($this->id); + $nbAnswers = $form->getSubmitValue('nb_answers'); + + $courseId = api_get_course_int_id(); + + $correct = []; + $options = Question::readQuestionOption($this->id, $courseId); + + if (!empty($options)) { + foreach ($options as $optionData) { + $id = $optionData['id']; + unset($optionData['id']); + Question::updateQuestionOption($id, $optionData, $courseId); + } + } else { + for ($i = 1; $i <= 8; $i++) { + $lastId = Question::saveQuestionOption($this->id, $this->options[$i], $courseId, $i); + $correct[$i] = $lastId; + } + } + + /* Getting quiz_question_options (true, false, doubt) because + it's possible that there are more options in the future */ + + $newOptions = Question::readQuestionOption($this->id, $courseId); + + $sortedByPosition = []; + foreach ($newOptions as $item) { + $sortedByPosition[$item['position']] = $item; + } + + /* Saving quiz_question.extra values that has the correct scores of + the true, false, doubt options registered in this format + XX:YY:ZZZ where XX is a float score value. */ + $extraValues = []; + + for ($i = 1; $i <= 3; $i++) { + $score = trim($form->getSubmitValue('option['.$i.']')); + $extraValues[] = $score; + } + $this->setExtra(implode(':', $extraValues)); + + for ($i = 1; $i <= $nbAnswers; $i++) { + $answer = trim($form->getSubmitValue('answer['.$i.']')); + $comment = trim($form->getSubmitValue('comment['.$i.']')); + $goodAnswer = trim($form->getSubmitValue('correct['.$i.']')); + if (empty($options)) { + //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered + $goodAnswer = $sortedByPosition[$goodAnswer]['id']; + } + $questionWeighting += $extraValues[0]; //By default 0 has the correct answers + $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i); + } + + // saves the answers into the data base + $objAnswer->save(); + + // sets the total weighting of the question + $this->updateWeighting($questionWeighting); + $this->save($exercise); + } + + /** + * @param int $feedbackType + * @param int $counter + * @param float $score + * + * @return null|string + */ + public function return_header($feedbackType = null, $counter = null, $score = null) + { + $header = parent::return_header($feedbackType, $counter, $score); + $header .= '' + ; + if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { + $header .= ''; + } else { + $header .= ''; + } + $header .= ''; + + return $header; + } + + /** + * Method to recovery color to show by precision of the student's answer. + * + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * + * @return string + */ + public function getColorResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) + { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) { + return '#088A08'; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return '#A9F5A9'; + } + if ($studentDegreeChoicePosition == 3) { + return '#FFFFFF'; + } + } else { + if ($studentDegreeChoicePosition >= 6) { + return '#FE2E2E'; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return '#F6CECE'; + } + if ($studentDegreeChoicePosition == 3) { + return '#FFFFFF'; + } + } + } + + /** + * Return the color code for student answer. + * + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * + * @return int + */ + public function getStatusResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) + { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) { + return self::LEVEL_DARKGREEN; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return self::LEVEL_LIGHTGREEN; + } + if ($studentDegreeChoicePosition == 3) { + return self::LEVEL_WHITE; + } + } else { + if ($studentDegreeChoicePosition >= 6) { + return self::LEVEL_DARKRED; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return self::LEVEL_LIGHTRED; + } + if ($studentDegreeChoicePosition == 3) { + return self::LEVEL_WHITE; + } + } + } + + /** + * Method to recovery lable for codes colors. + * + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * + * @return string + */ + public function getCodeResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) + { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) { + return get_lang('langVerySure'); + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return get_lang('langPrettySur'); + } + if ($studentDegreeChoicePosition == 3) { + return get_lang('langIgnorance'); + } + } else { + if ($studentDegreeChoicePosition >= 6) { + return get_lang('langVeryUnsure'); + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return get_lang('langUnsure'); + } + if ($studentDegreeChoicePosition == 3) { + return get_lang('langIgnorance'); + } + } + } + + /** + * Method to show the code color and his meaning for the test result. + */ + public static function showColorCode() + { ?>
' + .get_lang("Choice") + .'' + .get_lang("ExpectedChoice") + .'' + .get_lang("Answer") + .'' + .get_lang("YourDegreeOfCertainty") + .' '.get_lang("Comment").' 
@@ -438,163 +468,160 @@ public static function showColorCode() {

- gather_questions_categories == 1) { // original - $groupCategoriesByBracket = true; - } else { - $groupCategoriesByBracket = false; - } - - if ($groupCategoriesByBracket) { - $scoreList = []; - $categoryPrefixList = []; // categoryPrefix['Math'] = firstCategoryId for this prefix - // rebuild $scoreList factirizing datas with caregory prefix - foreach ($scoreListAll as $categoryId => $scoreListForCategory) { - $objCategory = new Testcategory(); - $objCategoryNum = $objCategory->getCategory($categoryId); - preg_match("/^\[([^]]+)\]/", $objCategoryNum->name, $matches); - - if (count($matches) > 1) { - // check if we have already see this prefix - if (array_key_exists($matches[1], $categoryPrefixList)) { - // add the result color for this entry - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKGREEN] += $scoreListForCategory[self::LEVEL_DARKGREEN]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTGREEN] += $scoreListForCategory[self::LEVEL_LIGHTGREEN]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_WHITE] += $scoreListForCategory[self::LEVEL_WHITE]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTRED] += $scoreListForCategory[self::LEVEL_LIGHTRED]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKRED] += $scoreListForCategory[self::LEVEL_DARKRED]; - - } else { - $categoryPrefixList[$matches[1]] = $categoryId; - $scoreList[$categoryId] = $scoreListAll[$categoryId]; - } - } else { - // dont matche the prefix '[math] Math category' - $scoreList[$categoryId] = $scoreListAll[$categoryId]; - } - } - } else { - $scoreList = $scoreListAll; - } - - - // get the max height of item to have each table the same height if displayed side by side - foreach ($scoreList as $categoryId => $scoreListForCategory) { - $testCategorie = new TestCategory(); - $categorieQuestionName = $testCategorie->getCategory($categoryId)->name; - list($null, $height) = self::displayDegreeChart( - $scoreListForCategory, - 300, - '', - 1, - 0, - false, - true, - groupCategoriesByBracket - ); - if ($height > $maxHeight) { - $maxHeight = $height; - } - } - - if (count($scoreList) > 1) { - $boxWidth = $sizeRatio * 300 * 2 + 54; - } else { - $boxWidth = $sizeRatio * 300 + 54; - } - - $html = '
'; - $html .= '

' . $title . '

'; - - // get the html of items - $i = 0; - foreach ($scoreList as $categoryId => $scoreListForCategory) { - $oCategory = new Testcategory(); - $categorieQuestionName = $oCategory->getCategory($categoryId)->name; - - if ($categorieQuestionName == '') { - $categoryName = get_lang('NonCategory'); - } else { - $categoryName = $oCategory->name; - } - - $html .= '
'; - $html .= self::displayDegreeChart( - $scoreListForCategory, - 300, - $categoryName, - 1, - $maxHeight, - false, - false, - $groupCategoriesByBracket - ); - $html .= '
'; - - if ($i == 1) { - $html .= '
 
'; - $i = 0; - } else { - $i++; - } - } - - - return $html . '
 
'; - } - - /** - * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions - * @param $scoreList - * @param int $sizeRatio - * @return string - */ - public static function displayDegreeChart( - $scoreList, - $widthTable, - $title = '', - $sizeRatio = 1, - $minHeight = 0, - $displayExplanationText = true, - $returnHeight = false, - $groupCategoriesByBracket = false, - $numberOfQuestions = 0 - ) { - $topAndBottomMargin = 10; - - $colorList = [self::LEVEL_DARKRED, - self::LEVEL_LIGHTRED, - self::LEVEL_WHITE, - self::LEVEL_LIGHTGREEN, - self::LEVEL_DARKGREEN - ]; - - - // get total attempt number - $highterColorHeight = 0; - - foreach ($scoreList as $color => $number) { - if ($number > $highterColorHeight) { - $highterColorHeight = $number; - } - } - - $totalAttemptNumber = $numberOfQuestions; - - $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2; - if ($verticalLineHeight < $minHeight) { - $minHeightCorrection = $minHeight - $verticalLineHeight; - $verticalLineHeight += $minHeightCorrection; - } - - // draw chart + gather_questions_categories == 1) { // original + $groupCategoriesByBracket = true; + } else { + $groupCategoriesByBracket = false; + } + + if ($groupCategoriesByBracket) { + $scoreList = []; + $categoryPrefixList = []; // categoryPrefix['Math'] = firstCategoryId for this prefix + // rebuild $scoreList factirizing datas with caregory prefix + foreach ($scoreListAll as $categoryId => $scoreListForCategory) { + $objCategory = new Testcategory(); + $objCategoryNum = $objCategory->getCategory($categoryId); + preg_match("/^\[([^]]+)\]/", $objCategoryNum->name, $matches); + + if (count($matches) > 1) { + // check if we have already see this prefix + if (array_key_exists($matches[1], $categoryPrefixList)) { + // add the result color for this entry + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKGREEN] += $scoreListForCategory[self::LEVEL_DARKGREEN]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTGREEN] += $scoreListForCategory[self::LEVEL_LIGHTGREEN]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_WHITE] += $scoreListForCategory[self::LEVEL_WHITE]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTRED] += $scoreListForCategory[self::LEVEL_LIGHTRED]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKRED] += $scoreListForCategory[self::LEVEL_DARKRED]; + } else { + $categoryPrefixList[$matches[1]] = $categoryId; + $scoreList[$categoryId] = $scoreListAll[$categoryId]; + } + } else { + // dont matche the prefix '[math] Math category' + $scoreList[$categoryId] = $scoreListAll[$categoryId]; + } + } + } else { + $scoreList = $scoreListAll; + } + + // get the max height of item to have each table the same height if displayed side by side + foreach ($scoreList as $categoryId => $scoreListForCategory) { + $testCategorie = new TestCategory(); + $categorieQuestionName = $testCategorie->getCategory($categoryId)->name; + list($null, $height) = self::displayDegreeChart( + $scoreListForCategory, + 300, + '', + 1, + 0, + false, + true, + groupCategoriesByBracket + ); + if ($height > $maxHeight) { + $maxHeight = $height; + } + } + + if (count($scoreList) > 1) { + $boxWidth = $sizeRatio * 300 * 2 + 54; + } else { + $boxWidth = $sizeRatio * 300 + 54; + } + + $html = '
'; + $html .= '

'.$title.'

'; + + // get the html of items + $i = 0; + foreach ($scoreList as $categoryId => $scoreListForCategory) { + $oCategory = new Testcategory(); + $categorieQuestionName = $oCategory->getCategory($categoryId)->name; + + if ($categorieQuestionName == '') { + $categoryName = get_lang('NonCategory'); + } else { + $categoryName = $oCategory->name; + } + + $html .= '
'; + $html .= self::displayDegreeChart( + $scoreListForCategory, + 300, + $categoryName, + 1, + $maxHeight, + false, + false, + $groupCategoriesByBracket + ); + $html .= '
'; + + if ($i == 1) { + $html .= '
 
'; + $i = 0; + } else { + $i++; + } + } + + return $html.'
 
'; + } + + /** + * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions. + * + * @param $scoreList + * @param int $sizeRatio + * + * @return string + */ + public static function displayDegreeChart( + $scoreList, + $widthTable, + $title = '', + $sizeRatio = 1, + $minHeight = 0, + $displayExplanationText = true, + $returnHeight = false, + $groupCategoriesByBracket = false, + $numberOfQuestions = 0 + ) { + $topAndBottomMargin = 10; + + $colorList = [self::LEVEL_DARKRED, + self::LEVEL_LIGHTRED, + self::LEVEL_WHITE, + self::LEVEL_LIGHTGREEN, + self::LEVEL_DARKGREEN, + ]; + + // get total attempt number + $highterColorHeight = 0; + + foreach ($scoreList as $color => $number) { + if ($number > $highterColorHeight) { + $highterColorHeight = $number; + } + } + + $totalAttemptNumber = $numberOfQuestions; + + $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2; + if ($verticalLineHeight < $minHeight) { + $minHeightCorrection = $minHeight - $verticalLineHeight; + $verticalLineHeight += $minHeightCorrection; + } + + // draw chart $html = ''; - - if ($groupCategoriesByBracket) { - $title = api_preg_replace("/[^]]*$/", "", $title); - $title = ucfirst(api_preg_replace("/[\[\]]/", "", $title)); - } - - $affiche = (strpos($title, "ensemble") > 0) ? - $title . "
($totalAttemptNumber questions)" : - $title; - $textSize = ( - strpos($title, "ensemble") > 0 || - strpos($title, "votre dernier résultat à ce test") > 0 - ) ? 100 : 80; - - if ($displayExplanationText) { - // global chart - $classGlobalChart = "globalChart"; - } else { - $classGlobalChart = ""; - } - - $html .= '' - ; - $html .= '' - ; - - $nbResponsesInc = (isset($scoreList[4]) || isset($scoreList[5])) ? $scoreList[4] + $scoreList[5] : 0; - $nbResponsesIng = (isset($scoreList[3])) ? $scoreList[3] : 0; - $nbResponsesCor = (isset($scoreList[1]) || isset($scoreList[2])) ? $scoreList[1] + $scoreList[2] : 0; - - $colWidth = $widthTable / 5; - + '; + + if ($groupCategoriesByBracket) { + $title = api_preg_replace("/[^]]*$/", "", $title); + $title = ucfirst(api_preg_replace("/[\[\]]/", "", $title)); + } + + $affiche = (strpos($title, "ensemble") > 0) ? + $title."
($totalAttemptNumber questions)" : + $title; + $textSize = ( + strpos($title, "ensemble") > 0 || + strpos($title, "votre dernier résultat à ce test") > 0 + ) ? 100 : 80; + + if ($displayExplanationText) { + // global chart + $classGlobalChart = "globalChart"; + } else { + $classGlobalChart = ""; + } + + $html .= '
' - . $affiche - . '
' + ; + $html .= '' + ; + + $nbResponsesInc = (isset($scoreList[4]) || isset($scoreList[5])) ? $scoreList[4] + $scoreList[5] : 0; + $nbResponsesIng = (isset($scoreList[3])) ? $scoreList[3] : 0; + $nbResponsesCor = (isset($scoreList[1]) || isset($scoreList[2])) ? $scoreList[1] + $scoreList[2] : 0; + + $colWidth = $widthTable / 5; + $html .= ' - '; - $html .= ''; - - foreach ($colorList as $i => $color) { - if (array_key_exists($color, $scoreList)) { - $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom - } else { - $scoreOnBottom = 0; - } - - $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2 ; - - if ($i == 1 || $i == 2) { - $html .= ''; - } - - $html .= ''; - - if ($displayExplanationText) { - // affichage texte histogramme - $explainHistoList = array( - 'langVeryUnsure', - 'langUnsure', - 'langIgnorance', - 'langPrettySur', - 'langVerySure'); - $html .= ''; - $i = 0; - foreach ($explainHistoList as $explain) { - if ($i == 1 || $i == 2) { - $class = "borderRight"; - } else { - $class = ""; - } - $html .= ''; - $i++; - } - $html .= ''; - } - - $html .='
' + .$affiche + .'
'. + style="width:'.($colWidth * 2).'px; font-size:'.$textSize.'%;">'. get_lang('langWrongsAnswers').' : '.$nbResponsesInc.' '. + style="width:'.$colWidth.'px; font-size :'.$textSize.'%;">'. get_lang('langIgnoranceAnswers').' : '.$nbResponsesIng.' '. + style="width:'.($colWidth * 2).'px; font-size:'.$textSize.'%;">'. get_lang('langCorrectsAnswers').' : '.$nbResponsesCor.'
' - ; - } else { - $html .= '' - ; - } - $html .= '
' - . $scoreOnBottom - . '
 
' - ; - $html .= '
' - ; - $html .= get_lang($explain); - $html .= '
'; - - if ($returnHeight) { - return array($html, $verticalLineHeight); - } else { - return $html; - } - } - - /** - * return previous attempt id for this test for student, 0 if no previous attempt - * @param $exeId - * @return int - */ - public static function getPreviousAttemptId($exeId) { - $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + '; + $html .= ''; + + foreach ($colorList as $i => $color) { + if (array_key_exists($color, $scoreList)) { + $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom + } else { + $scoreOnBottom = 0; + } + + $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2; + + if ($i == 1 || $i == 2) { + $html .= '' + ; + } else { + $html .= '' + ; + } + $html .= '
' + .$scoreOnBottom + .'
 
' + ; + $html .= ''; + } + + $html .= ''; + + if ($displayExplanationText) { + // affichage texte histogramme + $explainHistoList = [ + 'langVeryUnsure', + 'langUnsure', + 'langIgnorance', + 'langPrettySur', + 'langVerySure', ]; + $html .= ''; + $i = 0; + foreach ($explainHistoList as $explain) { + if ($i == 1 || $i == 2) { + $class = "borderRight"; + } else { + $class = ""; + } + $html .= '' + ; + $html .= get_lang($explain); + $html .= ''; + $i++; + } + $html .= ''; + } + + $html .= ''; + + if ($returnHeight) { + return [$html, $verticalLineHeight]; + } else { + return $html; + } + } + + /** + * return previous attempt id for this test for student, 0 if no previous attempt. + * + * @param $exeId + * + * @return int + */ + public static function getPreviousAttemptId($exeId) + { + $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); $sql = "SELECT * FROM $tblTrackEExercise - WHERE exe_id = " . intval($exeId); - $res = Database::query($sql); - - if (Database::num_rows($res) == 0) { - // if we cannot find the exe_id - return 0; - } - - $data = Database::fetch_assoc($res); - $courseCode = $data['exe_cours_id']; - $exerciseId = $data['exe_exo_id']; - $userId = $data['exe_user_id']; - $attemptDate = $data['exe_date']; - - if ($attemptDate == "0000-00-00 00:00:00") { - // incomplete attempt, close it before continue - return 0; - } - - // look for previous attempt + WHERE exe_id = ".intval($exeId); + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + // if we cannot find the exe_id + return 0; + } + + $data = Database::fetch_assoc($res); + $courseCode = $data['exe_cours_id']; + $exerciseId = $data['exe_exo_id']; + $userId = $data['exe_user_id']; + $attemptDate = $data['exe_date']; + + if ($attemptDate == "0000-00-00 00:00:00") { + // incomplete attempt, close it before continue + return 0; + } + + // look for previous attempt $sql = "SELECT * FROM $tblTrackEExercise - WHERE c_id = '" . $courseCode . "' - AND exe_exo_id = " . intval($exerciseId) . " - AND exe_user_id = " . intval($userId) . " + WHERE c_id = '".$courseCode."' + AND exe_exo_id = ".intval($exerciseId)." + AND exe_user_id = ".intval($userId)." AND status = '' AND exe_date > '0000-00-00 00:00:00' - AND exe_date < '" . $attemptDate . "' - ORDER BY exe_date DESC"; - - $res = Database::query($sql); - - if (Database::num_rows($res) == 0) { - // no previous attempt - return 0; - } - - $data = Database::fetch_assoc($res); - return $data['exe_id']; - } - - /** - * return an array of number of answer color for exe attempt for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY - * e.g. - * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0] - * @param $exeId - * @return array - */ - public static function getColorNumberListForAttempt($exeId) { - $result = [self::LEVEL_DARKGREEN => 0, - self::LEVEL_LIGHTGREEN => 0, - self::LEVEL_WHITE => 0, - self::LEVEL_LIGHTRED => 0, - self::LEVEL_DARKRED => 0 - ]; - - $attemptInfoList = self::getExerciseAttemptInfo($exeId); - - foreach ($attemptInfoList as $i => $attemptInfo) { - $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); - $oQuestion->read($attemptInfo['question_id']); - if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { - $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); - if ($answerColor) { - $result[$answerColor] ++; - } - } - } - return $result; - } - - /** - * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY - * for each question category - * - * e.g. - * [ - * (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12] - * (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8] - * (categoryId=)0 => [LEVEL_DARKGREEN => 1, LEVEL_LIGHTGREEN => 2, LEVEL_WHITE => 6, LEVEL_LIGHTRED => 1, LEVEL_DARKTRED => 9] - * ] - * @param $exeId - * @return array - */ - public static function getColorNumberListForAttemptByCategory($exeId) { - $result = array(); - $attemptInfoList = self::getExerciseAttemptInfo($exeId); - - foreach ($attemptInfoList as $i => $attemptInfo) { - $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); - $oQuestion->read($attemptInfo['question_id']); - if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { - $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']); - - if (!array_key_exists($questionCategory, $result)) { - $result[$questionCategory] = array(); - } - - $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); - if ($answerColor) { - $result[$questionCategory][$answerColor] ++; - } - } - } - return $result; - } - - /** - * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false - * @param $exeId - * @param $questionId - * @param $position - * @return bool - */ - public static function getAnswerColor($exeId, $questionId, $position) { - $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position); - - if (count($attemptInfoList) != 1) { - // havent got the answer - return 0; - } - - $answerCodes = $attemptInfoList[0]['answer']; - - // student answer - $splitAnswer = preg_split("/:/", $answerCodes); - // get correct answer option id - $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]); - if ($correctAnswerOptionId == 0) { - // error returning the correct answer option id - return 0; - } - - // get student answer option id - $studentAnswerOptionId = $splitAnswer[1]; - - // we got the correct answer option id, let's compare ti with the student answer - $percentage = self::getPercentagePosition($splitAnswer[2]); - if ($studentAnswerOptionId == $correctAnswerOptionId) { - // yeah, student got correct answer - switch ($percentage) { - case 3 : - return self::LEVEL_WHITE; - case 4 : - case 5 : - return self::LEVEL_LIGHTGREEN; - case 6 : - case 7 : - case 8 : - return self::LEVEL_DARKGREEN; - default : - return 0; - } - } else { - // bummer, wrong answer dude - switch ($percentage) { - case 3 : - return self::LEVEL_WHITE; - case 4 : - case 5 : - return self::LEVEL_LIGHTRED; - case 6 : - case 7 : - case 8 : - return self::LEVEL_DARKRED; - default : - return 0; - } - } - } - - /** - * Return the position of certitude %age choose by student - * @param $optionId - * @return int - */ - public static function getPercentagePosition($optionId) { - $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION); - $courseId = api_get_course_int_id(); + AND exe_date < '".$attemptDate."' + ORDER BY exe_date DESC"; + + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + // no previous attempt + return 0; + } + + $data = Database::fetch_assoc($res); + + return $data['exe_id']; + } + + /** + * return an array of number of answer color for exe attempt for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + * e.g. + * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0]. + * + * @param $exeId + * + * @return array + */ + public static function getColorNumberListForAttempt($exeId) + { + $result = [self::LEVEL_DARKGREEN => 0, + self::LEVEL_LIGHTGREEN => 0, + self::LEVEL_WHITE => 0, + self::LEVEL_LIGHTRED => 0, + self::LEVEL_DARKRED => 0, + ]; + + $attemptInfoList = self::getExerciseAttemptInfo($exeId); + + foreach ($attemptInfoList as $i => $attemptInfo) { + $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); + $oQuestion->read($attemptInfo['question_id']); + if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); + if ($answerColor) { + $result[$answerColor]++; + } + } + } + + return $result; + } + + /** + * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + * for each question category. + * + * e.g. + * [ + * (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12] + * (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8] + * (categoryId=)0 => [LEVEL_DARKGREEN => 1, LEVEL_LIGHTGREEN => 2, LEVEL_WHITE => 6, LEVEL_LIGHTRED => 1, LEVEL_DARKTRED => 9] + * ] + * + * @param $exeId + * + * @return array + */ + public static function getColorNumberListForAttemptByCategory($exeId) + { + $result = []; + $attemptInfoList = self::getExerciseAttemptInfo($exeId); + + foreach ($attemptInfoList as $i => $attemptInfo) { + $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); + $oQuestion->read($attemptInfo['question_id']); + if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']); + + if (!array_key_exists($questionCategory, $result)) { + $result[$questionCategory] = []; + } + + $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); + if ($answerColor) { + $result[$questionCategory][$answerColor]++; + } + } + } + + return $result; + } + + /** + * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false. + * + * @param $exeId + * @param $questionId + * @param $position + * + * @return bool + */ + public static function getAnswerColor($exeId, $questionId, $position) + { + $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position); + + if (count($attemptInfoList) != 1) { + // havent got the answer + return 0; + } + + $answerCodes = $attemptInfoList[0]['answer']; + + // student answer + $splitAnswer = preg_split("/:/", $answerCodes); + // get correct answer option id + $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]); + if ($correctAnswerOptionId == 0) { + // error returning the correct answer option id + return 0; + } + + // get student answer option id + $studentAnswerOptionId = $splitAnswer[1]; + + // we got the correct answer option id, let's compare ti with the student answer + $percentage = self::getPercentagePosition($splitAnswer[2]); + if ($studentAnswerOptionId == $correctAnswerOptionId) { + // yeah, student got correct answer + switch ($percentage) { + case 3: + return self::LEVEL_WHITE; + case 4: + case 5: + return self::LEVEL_LIGHTGREEN; + case 6: + case 7: + case 8: + return self::LEVEL_DARKGREEN; + default: + return 0; + } + } else { + // bummer, wrong answer dude + switch ($percentage) { + case 3: + return self::LEVEL_WHITE; + case 4: + case 5: + return self::LEVEL_LIGHTRED; + case 6: + case 7: + case 8: + return self::LEVEL_DARKRED; + default: + return 0; + } + } + } + + /** + * Return the position of certitude %age choose by student. + * + * @param $optionId + * + * @return int + */ + public static function getPercentagePosition($optionId) + { + $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION); + $courseId = api_get_course_int_id(); $sql = "SELECT position FROM $tblAnswerOption - WHERE c_id = " . intval($courseId) . " - AND id = " . intval($optionId); - $res = Database::query($sql); - - if (Database::num_rows($res) == 0) { - return 0; - } - - $data = Database::fetch_assoc($res); - return $data['position']; - } - - /** - * return the correct id from c_quiz_question_option for question idAuto - * @param $idAuto - * @return int - */ - public static function getCorrectAnswerOptionId($idAuto) { - $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER); - $courseId = api_get_course_int_id(); + WHERE c_id = ".intval($courseId)." + AND id = ".intval($optionId); + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + return 0; + } + + $data = Database::fetch_assoc($res); + + return $data['position']; + } + + /** + * return the correct id from c_quiz_question_option for question idAuto. + * + * @param $idAuto + * + * @return int + */ + public static function getCorrectAnswerOptionId($idAuto) + { + $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER); + $courseId = api_get_course_int_id(); $sql = "SELECT correct FROM $tblAnswer - WHERE c_id = " . intval($courseId) . " - AND id_auto = " . intval($idAuto); - - $res = Database::query($sql); - $data = Database::fetch_assoc($res); - if (Database::num_rows($res) > 0) { - return $data['correct']; - } else { - return 0; - } - } - - /** - * return an array of exe info from track_e_attempt - * @param $exeId - * @param int $questionId - * @param int $position - * @return array - */ - public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1) { - $result = array(); - $and = ''; - - if ($questionId >= 0) { - $and .= " AND question_id = " . intval($questionId); - } - if ($position >= 0) { - $and .= " AND position = " . intval($position); - } - - $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); - $cId = api_get_course_int_id(); + WHERE c_id = ".intval($courseId)." + AND id_auto = ".intval($idAuto); + + $res = Database::query($sql); + $data = Database::fetch_assoc($res); + if (Database::num_rows($res) > 0) { + return $data['correct']; + } else { + return 0; + } + } + + /** + * return an array of exe info from track_e_attempt. + * + * @param $exeId + * @param int $questionId + * @param int $position + * + * @return array + */ + public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1) + { + $result = []; + $and = ''; + + if ($questionId >= 0) { + $and .= " AND question_id = ".intval($questionId); + } + if ($position >= 0) { + $and .= " AND position = ".intval($position); + } + + $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + $cId = api_get_course_int_id(); $sql = "SELECT * FROM $tblExeAttempt WHERE c_id = $cId AND exe_id = $exeId - $and"; - - $res = Database::query($sql); - while ($data = Database::fetch_assoc($res)) { - $result[] = $data; - } - return $result; - } - - - public static function getNumberOfQuestionsForExeId($exeId) - { - $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + $and"; + + $res = Database::query($sql); + while ($data = Database::fetch_assoc($res)) { + $result[] = $data; + } + + return $result; + } + + public static function getNumberOfQuestionsForExeId($exeId) + { + $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); $sql = "SELECT exe_exo_id FROM $tableTrackEExercise - WHERE exe_id=".intval($exeId); - $res = Database::query($sql); - $data = Database::fetch_assoc($res); - $exerciseId = $data['exe_exo_id']; - - $objectExercise = new Exercise(); - $objectExercise->read($exerciseId); - - return $objectExercise->get_count_question_list(); - } - - /** - * Display student chart results for these question types - * @param $exeId - * @return string - */ - public static function displayStudentsChartResults($exeId, $objExercice) { - - $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId); - - $globalScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt($exeId); - $html = MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( - $globalScoreList, - 600, - get_lang('ResultTest'), - 2, - 0, - true, - false, - false, - $numberOfQuestions - ) - . "
" - ; - - $previousAttemptId = MultipleAnswerTrueFalseDegreeCertainty::getPreviousAttemptId($exeId); - if ($previousAttemptId > 0) { - $previousAttemptScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt( - $previousAttemptId - ); - $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( - $previousAttemptScoreList, - 600, - get_lang('CompareLastResult'), - 2 - ) - . "
" - ; - } - - $categoryScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttemptByCategory($exeId); - $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChartByCategory( - $categoryScoreList, - get_lang('ResultsbyDiscipline'), - 1 - ,$objExercice - ) - . "
" - ; - - return $html; - } - - } + WHERE exe_id=".intval($exeId); + $res = Database::query($sql); + $data = Database::fetch_assoc($res); + $exerciseId = $data['exe_exo_id']; + + $objectExercise = new Exercise(); + $objectExercise->read($exerciseId); + + return $objectExercise->get_count_question_list(); + } + + /** + * Display student chart results for these question types. + * + * @param $exeId + * + * @return string + */ + public static function displayStudentsChartResults($exeId, $objExercice) + { + $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId); + + $globalScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt($exeId); + $html = MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( + $globalScoreList, + 600, + get_lang('ResultTest'), + 2, + 0, + true, + false, + false, + $numberOfQuestions + ) + ."
" + ; + + $previousAttemptId = MultipleAnswerTrueFalseDegreeCertainty::getPreviousAttemptId($exeId); + if ($previousAttemptId > 0) { + $previousAttemptScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt( + $previousAttemptId + ); + $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( + $previousAttemptScoreList, + 600, + get_lang('CompareLastResult'), + 2 + ) + ."
" + ; + } + + $categoryScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttemptByCategory($exeId); + $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChartByCategory( + $categoryScoreList, + get_lang('ResultsbyDiscipline'), + 1, $objExercice + ) + ."
" + ; + + return $html; + } + } diff --git a/main/exercise/question.class.php b/main/exercise/question.class.php index a9e6339fbf8..1c9e042bdd0 100755 --- a/main/exercise/question.class.php +++ b/main/exercise/question.class.php @@ -52,7 +52,7 @@ abstract class Question MULTIPLE_ANSWER_TRUE_FALSE => ['multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'], MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY => [ 'multipleAnswerTrueFalseDegreeCertainty.php', - 'MultipleAnswerTrueFalseDegreeCertainty' + 'MultipleAnswerTrueFalseDegreeCertainty', ], MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE => [ 'multiple_answer_combination_true_false.class.php', @@ -1986,7 +1986,7 @@ public function return_header($exercise, $counter = null, $score = []) ]; $header .= Display::page_subheader2($counterLabel.'. '.$this->question); // dont display score for certainty degree questions - if($this->type != MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + if ($this->type != MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { $header .= $exercise->getQuestionRibbon($class, $score_label, $score['result'], $scoreCurrent); } diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index d070347c9d8..12c3f68cf19 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -6160,6 +6160,7 @@ function api_is_element_in_the_session($tool, $element_id, $session_id = null) return true; } } + return false; } @@ -9022,8 +9023,9 @@ function api_float_val($number) * * @todo WIP * - * @param string $number number in iso code + * @param string $number number in iso code * @param int $decimals + * * @return bool|string */ function api_number_format($number, $decimals = 0) diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index 5e212057d6f..36923a6b7d4 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -248,7 +248,7 @@ public static function showQuestion( $header, ['style' => 'text-align:left;'] ); - } else if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ + } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { echo ""; - $header = Display::tag('th', get_lang('Options'), array('width' => '50%')); + $header = Display::tag('th', get_lang('Options'), ['width' => '50%']); foreach ($objQuestionTmp->optionsTitle as $item) { if (in_array($item, $objQuestionTmp->optionsTitle)) { - $properties = array(); + $properties = []; if ($item == "langAnswers") { $properties["colspan"] = 2; $properties["style"] = "background-color: #F56B2A; color: #ffffff;"; - } else if ($item == "DegreeOfCertainty") { + } elseif ($item == "DegreeOfCertainty") { $properties["colspan"] = 6; $properties["style"] = "background-color: #330066; color: #ffffff;"; } @@ -364,7 +364,6 @@ function handleRadioRow(event, question_id, answer_id) { $header .= Display::tag('th', get_lang('Feedback')); } - $s .= ''; $s .= Display::tag('tr', $header, ['style' => 'text-align:left;']); @@ -372,14 +371,13 @@ function handleRadioRow(event, question_id, answer_id) { $header1 = Display::tag('th', ' '); $cpt1 = 0; foreach ($objQuestionTmp->options as $item) { - $colorBorder1 =($cpt1 == (count($objQuestionTmp->options)-1))?'':'border-right: solid #FFFFFF 1px;' ; + $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] + ['style' => 'background-color: #F7C9B4; color: black;'.$colorBorder1] ); } else { - $header1 .= Display::tag('th', $item, ['style' => 'background-color: #e6e6ff; color: black;padding:5px; '.$colorBorder1]); @@ -400,27 +398,25 @@ function handleRadioRow(event, question_id, answer_id) { get_lang('Unsure'), get_lang('PrettySur'), get_lang('Sur'), - get_lang('VerySur') + get_lang('VerySur'), ]; $counter2 = 0; foreach ($objQuestionTmp->options as $item) { - if ($item == "True" || $item == "False") { $header2 .= Display::tag('td', ' ', ['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;' ; + $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)); + ['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', ' '); @@ -658,7 +654,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $s .= ''; } $s .= ''; - } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ + } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { $myChoice = []; if (!empty($userChoiceList)) { foreach ($userChoiceList as $item) { @@ -677,17 +673,15 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $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 . ')'; + $attributes['onChange'] = 'RadioValidator('.$questionId.', '.$numAnswer.')'; // gère la séletion des radio button du degré de certitude - if (isset($myChoiceDegreeCertainty[$numAnswer]) && + if (isset($myChoiceDegreeCertainty[$numAnswer]) && $id == $myChoiceDegreeCertainty[$numAnswer] ) { $attributes1 = ['checked' => 1, 'selected' => 1]; @@ -695,7 +689,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $attributes1 = []; } - $attributes1['onChange'] = 'RadioValidator(' . $questionId . ', ' . $numAnswer . ')'; + $attributes1['onChange'] = 'RadioValidator('.$questionId.', '.$numAnswer.')'; if ($debug_mark_answer) { if ($id == $answerCorrect) { @@ -707,27 +701,27 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" if ($item["name"] == "True" || $item["name"] == "False") { $s .= Display::tag('td', Display::input('radio', - 'choice[' . $questionId . '][' . $numAnswer . ']', + 'choice['.$questionId.']['.$numAnswer.']', $id, $attributes ), ['style' => 'text-align:center; background-color:#F7E1D7;', - 'onclick' => 'handleRadioRow(event, ' . - $questionId . ', ' . - $numAnswer . ')' + 'onclick' => 'handleRadioRow(event, '. + $questionId.', '. + $numAnswer.')', ] ); } else { $s .= Display::tag('td', Display::input('radio', - 'choiceDegreeCertainty[' . $questionId . '][' . $numAnswer . ']', + 'choiceDegreeCertainty['.$questionId.']['.$numAnswer.']', $id, $attributes1 ), ['style' => 'text-align:center; background-color:#EFEFFC;', - 'onclick' => 'handleRadioRow(event, ' . - $questionId . ', ' . - $numAnswer . ')' + 'onclick' => 'handleRadioRow(event, '. + $questionId.', '. + $numAnswer.')', ] ); } @@ -739,7 +733,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $s .= $comment; $s .= ''; } - $s.=''; + $s .= ''; } break; case MULTIPLE_ANSWER_COMBINATION: @@ -924,7 +918,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" 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']; @@ -947,7 +941,7 @@ class="exercise-unique-answer-image col-xs-6 col-md-3" $correctAnswerList ); - // get student answer to display it if student go back + // 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( @@ -1338,7 +1332,7 @@ class="window window_left_question window{$questionId}_question"> UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE, - MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY, ] )) { $s .= '
'; @@ -1944,9 +1938,9 @@ public static function getLatestHotPotatoResult( * @param null $extra_where_conditions * @param bool $get_count * @param string $courseCode - * @param bool $showSessionField - * @param bool $showExerciseCategories - * @param array $userExtraFieldsToAdd + * @param bool $showSessionField + * @param bool $showExerciseCategories + * @param array $userExtraFieldsToAdd * * @return array */ @@ -2699,10 +2693,10 @@ public static function get_exam_results_data( * * @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 + * @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 */ @@ -3731,6 +3725,7 @@ public static function get_student_stats_by_question( * * @param int $question_id * @param int $exercise_id + * * @return int */ public static function getNumberStudentsFillBlanksAnswerCount( @@ -4219,9 +4214,10 @@ public static function get_number_students_finish_exercise( } /** - * @param string $in_name is the name and the id of the + * @param string $in_default default value for option * @param string $in_onchange + * * @return string the html code of the "; + return $res; } @@ -4585,7 +4582,7 @@ public static function displayQuestionListByAttempt( echo "

Vos Résultats


"; } $totalScoreText .= '
'; - if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ + if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { $totalScoreText .= self::getQuestionRibbonDiag($objExercise, $total_score, $total_weight, @@ -4603,7 +4600,7 @@ public static function displayQuestionListByAttempt( $totalScoreText .= '
'; } - if($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY){ + if ($result['answer_type'] == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { $chartMultiAnswer = MultipleAnswerTrueFalseDegreeCertainty::displayStudentsChartResults( $exeId, $objExercise); @@ -4693,15 +4690,16 @@ public static function displayQuestionListByAttempt( /** * @param Exercise $objExercise - * @param float $score - * @param float $weight - * @param bool $checkPassPercentage + * @param float $score + * @param float $weight + * @param bool $checkPassPercentage + * * @return string */ - public static function getQuestionRibbonDiag($objExercise, $score, $weight, $checkPassPercentage = false) { - + public static function getQuestionRibbonDiag($objExercise, $score, $weight, $checkPassPercentage = false) + { $displayChartDegree = true; - $ribbon = $displayChartDegree? '
' : ''; + $ribbon = $displayChartDegree ? '
' : ''; if ($checkPassPercentage) { $isSuccess = self::isSuccessExerciseResult( @@ -4716,14 +4714,13 @@ public static function getQuestionRibbonDiag($objExercise, $score, $weight, $che $ribbonTotalSuccessOrError = ' ribbon-total-error'; } } - $ribbon .= $displayChartDegree? '
' : ''; + $ribbon .= $displayChartDegree ? '
' : ''; } else { - $ribbon .= $displayChartDegree? '
' : ''; + $ribbon .= $displayChartDegree ? '
' : ''; } - if ($displayChartDegree){ - $ribbon .= '

' . get_lang('YourTotalScore') . ": "; - + if ($displayChartDegree) { + $ribbon .= '

'.get_lang('YourTotalScore').": "; $ribbon .= self::show_score($score, $weight, false, true); $ribbon .= '

'; @@ -4736,12 +4733,11 @@ public static function getQuestionRibbonDiag($objExercise, $score, $weight, $che ); } - $ribbon .= $displayChartDegree? '
' : ''; + $ribbon .= $displayChartDegree ? '
' : ''; return $ribbon; } - /** * @param Exercise $objExercise * @param float $score diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 79b034709e1..98cdbc9eec5 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -497,21 +497,20 @@ public static function display_multiple_answer_true_false( } /** - * Display the answers to a multiple choice question + * 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 + * @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 bool $inResultsDisabled */ - static function displayMultipleAnswerTrueFalseDegreeCertainty ( + public static function displayMultipleAnswerTrueFalseDegreeCertainty( $feedbackType, $studentChoice, $studentChoiceDegree, @@ -521,49 +520,43 @@ static function displayMultipleAnswerTrueFalseDegreeCertainty ( $questionId, $inResultsDisabled ) { - $hideExpectedAnswer = false; if ($feedbackType == 0 && $inResultsDisabled == 2) { $hideExpectedAnswer = true; - } - ?> + } ?> + //Your choice + if (isset($newOptions[$studentChoice])) { + echo get_lang($newOptions[$studentChoice]['name']); + } else { + echo '-'; + } ?> + } ?> + echo $newOptions[$studentChoiceDegree]['name']; ?> getCodeResponse($studentChoice, + if ($degreCertitudeColor == "#088A08" || $degreCertitudeColor == "#FE2E2E") { + $color = "#FFFFFF"; + } else { + $color = "#000000"; + } + $codeResponse = $question->getCodeResponse($studentChoice, $answerCorrect, $newOptions[$studentChoiceDegree]['position'] - ); - ?> + ); ?>
- + ' . nl2br($answerComment) . ''; - } - ?> + echo ''.nl2br($answerComment).''; + } ?> - +   - + Date: Thu, 12 Jul 2018 14:55:36 +0200 Subject: [PATCH 17/30] Update exercise_show_functions.lib.php --- main/inc/lib/exercise_show_functions.lib.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 98cdbc9eec5..0f6c6674bff 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -574,7 +574,10 @@ public static function displayMultipleAnswerTrueFalseDegreeCertainty( $newOptions[$studentChoiceDegree]['position'] ); ?> -
+
+
From 4bd1afcb35781853459cc2c65474dc495e62659b Mon Sep 17 00:00:00 2001 From: pielRouge Date: Thu, 12 Jul 2018 14:58:39 +0200 Subject: [PATCH 18/30] Update multipleAnswerTrueFalseDegreeCertainty.php --- ...multipleAnswerTrueFalseDegreeCertainty.php | 2107 +++++++++-------- 1 file changed, 1062 insertions(+), 1045 deletions(-) diff --git a/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php b/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php index 6b388880121..e7b9631330f 100644 --- a/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php +++ b/main/exercise/multipleAnswerTrueFalseDegreeCertainty.php @@ -1,466 +1,477 @@ -type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY; - $this->isContent = $this->getIsContent(); - $this->optionsTitle = [1 => 'langAnswers', 2 => 'DegreeOfCertainty']; - $this->options = [ - 1 => 'True', - 2 => 'False', - 3 => '50%', - 4 => '60%', - 5 => '70%', - 6 => '80%', - 7 => '90%', - 8 => '100%', - ]; - } - - /** - * function which redefines Question::createAnswersForm. - * - * @param FormValidator $form - */ - public function createAnswersForm($form) - { - $nbAnswers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4; - // The previous default value was 2. See task #1759. - $nbAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); - - $courseId = api_get_course_int_id(); - $objEx = $_SESSION['objExercise']; - $renderer = &$form->defaultRenderer(); - $defaults = []; - - $html = ''; - - // show column comment when feedback is enable - if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { - $html .= ''; - } - $html .= ''; - $form->addElement('label', get_lang('Answers').'
', $html); - - $correct = 0; - $answer = null; - if (!empty($this->id)) { - $answer = new Answer($this->id); - $answer->read(); - if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) { - $nbAnswers = $answer->nbrAnswers; - } - } - - $form->addElement('hidden', 'nb_answers'); - $boxesNames = []; - - if ($nbAnswers < 1) { - $nbAnswers = 1; - Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer')); - } - - // Can be more options - $optionData = Question::readQuestionOption($this->id, $courseId); - - for ($i = 1; $i <= $nbAnswers; ++$i) { - $renderer->setElementTemplate( - '', - 'correct['.$i.']' - ); - $renderer->setElementTemplate( - '', - 'counter['.$i.']' - ); - $renderer->setElementTemplate( - '', - 'answer['.$i.']' - ); - $renderer->setElementTemplate( - '', - 'comment['.$i.']' - ); - - $answerNumber = $form->addElement('text', 'counter['.$i.']', null, 'value="'.$i.'"'); - $answerNumber->freeze(); - - if (is_object($answer)) { - $defaults['answer['.$i.']'] = $answer->answer[$i]; - $defaults['comment['.$i.']'] = $answer->comment[$i]; - $defaults['weighting['.$i.']'] = float_format($answer->weighting[$i], 1); - - $correct = $answer->correct[$i]; - $defaults['correct['.$i.']'] = $correct; - - $j = 1; - if (!empty($optionData)) { - foreach ($optionData as $id => $data) { - $form->addElement('radio', 'correct['.$i.']', null, null, $id); - $j++; - if ($j == 3) { - break; - } - } - } - } else { - $form->addElement('radio', 'correct['.$i.']', null, null, 1); - $form->addElement('radio', 'correct['.$i.']', null, null, 2); - - $defaults['answer['.$i.']'] = ''; - $defaults['comment['.$i.']'] = ''; - $defaults['correct['.$i.']'] = ''; - } - - $boxesNames[] = 'correct['.$i.']'; - $form->addElement( - 'html_editor', - 'answer['.$i.']', - null, - 'style="vertical-align:middle"', - ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']); - $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required'); - - // show comment when feedback is enable - if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { - $form->addElement('html_editor', - 'comment['.$i.']', - null, - 'style="vertical-align:middle"', - ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']); - } - $form->addElement('html', ''); - } - - $form->addElement('html', '
' - .get_lang('Number') - .'' - .get_lang('True') - .'' - .get_lang('False') - .'' - .get_lang('Answer') - .''.get_lang('Comment').'
{error}
{element}
{error}
{element}
{error}
{element}
{error}
{element}
'); - $form->addElement('html', '
'); - - // 3 scores - $form->addElement('text', 'option[1]', get_lang('Correct'), ['class' => 'span1', 'value' => '1']); - $form->addElement('text', 'option[2]', get_lang('Wrong'), ['class' => 'span1', 'value' => '-0.5']); - - $form->addElement('hidden', 'option[3]', 0); - - $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required'); - $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required'); - - $form->addElement('html', ''); - $form->addElement('hidden', 'options_count', 3); - $form->addElement('html', '


'); - - //Extra values True, false, Dont known - if (!empty($this->extra)) { - $scores = explode(':', $this->extra); - if (!empty($scores)) { - for ($i = 1; $i <= 3; $i++) { - $defaults['option['.$i.']'] = $scores[$i - 1]; - } - } - } - - global $text, $class; - if ($objEx->edit_exercise_in_lp == true) { - $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"'); - $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"'); - $form->addElement('submit', 'submitQuestion', $text, 'class="'.$class.'"'); - } - $renderer->setElementTemplate('{element} ', 'lessAnswers'); - $renderer->setElementTemplate('{element} ', 'submitQuestion'); - $renderer->setElementTemplate('{element} ', 'moreAnswers'); - $form->addElement('html', '
'); - $defaults['correct'] = $correct; - - if (!empty($this->id)) { - $form->setDefaults($defaults); - } else { - //if ($this -> isContent == 1) { - $form->setDefaults($defaults); - //} - } - $form->setConstants(['nb_answers' => $nbAnswers]); - } - - /** - * abstract function which creates the form to create / edit the answers of the question. - * - * @param FormValidator $form - * @param Exercise $exercise - */ - public function processAnswersCreation($form, $exercise) - { - $questionWeighting = $nbrGoodAnswers = 0; - $objAnswer = new Answer($this->id); - $nbAnswers = $form->getSubmitValue('nb_answers'); - - $courseId = api_get_course_int_id(); - - $correct = []; - $options = Question::readQuestionOption($this->id, $courseId); - - if (!empty($options)) { - foreach ($options as $optionData) { - $id = $optionData['id']; - unset($optionData['id']); - Question::updateQuestionOption($id, $optionData, $courseId); - } - } else { - for ($i = 1; $i <= 8; $i++) { - $lastId = Question::saveQuestionOption($this->id, $this->options[$i], $courseId, $i); - $correct[$i] = $lastId; - } - } - - /* Getting quiz_question_options (true, false, doubt) because - it's possible that there are more options in the future */ - - $newOptions = Question::readQuestionOption($this->id, $courseId); - - $sortedByPosition = []; - foreach ($newOptions as $item) { - $sortedByPosition[$item['position']] = $item; - } - - /* Saving quiz_question.extra values that has the correct scores of - the true, false, doubt options registered in this format - XX:YY:ZZZ where XX is a float score value. */ - $extraValues = []; - - for ($i = 1; $i <= 3; $i++) { - $score = trim($form->getSubmitValue('option['.$i.']')); - $extraValues[] = $score; - } - $this->setExtra(implode(':', $extraValues)); - - for ($i = 1; $i <= $nbAnswers; $i++) { - $answer = trim($form->getSubmitValue('answer['.$i.']')); - $comment = trim($form->getSubmitValue('comment['.$i.']')); - $goodAnswer = trim($form->getSubmitValue('correct['.$i.']')); - if (empty($options)) { - //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered - $goodAnswer = $sortedByPosition[$goodAnswer]['id']; - } - $questionWeighting += $extraValues[0]; //By default 0 has the correct answers - $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i); - } - - // saves the answers into the data base - $objAnswer->save(); - - // sets the total weighting of the question - $this->updateWeighting($questionWeighting); - $this->save($exercise); - } - - /** - * @param int $feedbackType - * @param int $counter - * @param float $score - * - * @return null|string - */ - public function return_header($feedbackType = null, $counter = null, $score = null) - { - $header = parent::return_header($feedbackType, $counter, $score); - $header .= '' - ; - if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { - $header .= ''; - } else { - $header .= ''; - } - $header .= ''; - - return $header; - } - - /** - * Method to recovery color to show by precision of the student's answer. - * - * @param $studentAnwser - * @param $expectedAnswer - * @param $studentDegreeChoicePosition - * - * @return string - */ - public function getColorResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) - { - $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; - if ($checkResult) { - if ($studentDegreeChoicePosition >= 6) { - return '#088A08'; - } - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { - return '#A9F5A9'; - } - if ($studentDegreeChoicePosition == 3) { - return '#FFFFFF'; - } - } else { - if ($studentDegreeChoicePosition >= 6) { - return '#FE2E2E'; - } - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { - return '#F6CECE'; - } - if ($studentDegreeChoicePosition == 3) { - return '#FFFFFF'; - } - } - } - - /** - * Return the color code for student answer. - * - * @param $studentAnwser - * @param $expectedAnswer - * @param $studentDegreeChoicePosition - * - * @return int - */ - public function getStatusResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) - { - $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; - if ($checkResult) { - if ($studentDegreeChoicePosition >= 6) { - return self::LEVEL_DARKGREEN; - } - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { - return self::LEVEL_LIGHTGREEN; - } - if ($studentDegreeChoicePosition == 3) { - return self::LEVEL_WHITE; - } - } else { - if ($studentDegreeChoicePosition >= 6) { - return self::LEVEL_DARKRED; - } - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { - return self::LEVEL_LIGHTRED; - } - if ($studentDegreeChoicePosition == 3) { - return self::LEVEL_WHITE; - } - } - } - - /** - * Method to recovery lable for codes colors. - * - * @param $studentAnwser - * @param $expectedAnswer - * @param $studentDegreeChoicePosition - * - * @return string - */ - public function getCodeResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) - { - $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; - if ($checkResult) { - if ($studentDegreeChoicePosition >= 6) { - return get_lang('langVerySure'); - } - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { - return get_lang('langPrettySur'); - } - if ($studentDegreeChoicePosition == 3) { - return get_lang('langIgnorance'); - } - } else { - if ($studentDegreeChoicePosition >= 6) { - return get_lang('langVeryUnsure'); - } - if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { - return get_lang('langUnsure'); - } - if ($studentDegreeChoicePosition == 3) { - return get_lang('langIgnorance'); - } - } - } - - /** - * Method to show the code color and his meaning for the test result. - */ - public static function showColorCode() - { +type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY; + $this->isContent = $this->getIsContent(); + $this->optionsTitle = [1 => 'langAnswers', 2 => 'DegreeOfCertainty']; + $this->options = [ + 1 => 'True', + 2 => 'False', + 3 => '50%', + 4 => '60%', + 5 => '70%', + 6 => '80%', + 7 => '90%', + 8 => '100%', + ]; + } + + /** + * function which redefines Question::createAnswersForm. + * + * @param FormValidator $form + */ + public function createAnswersForm($form) + { + $nbAnswers = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4; + // The previous default value was 2. See task #1759. + $nbAnswers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); + + $courseId = api_get_course_int_id(); + $objEx = $_SESSION['objExercise']; + $renderer = &$form->defaultRenderer(); + $defaults = []; + + $html = '
' - .get_lang("Choice") - .'' - .get_lang("ExpectedChoice") - .'' - .get_lang("Answer") - .'' - .get_lang("YourDegreeOfCertainty") - .' '.get_lang("Comment").' 
'; + + // show column comment when feedback is enable + if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + $html .= ''; + } + $html .= ''; + $form->addElement('label', get_lang('Answers').'
', $html); + + $correct = 0; + $answer = null; + if (!empty($this->id)) { + $answer = new Answer($this->id); + $answer->read(); + if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) { + $nbAnswers = $answer->nbrAnswers; + } + } + + $form->addElement('hidden', 'nb_answers'); + $boxesNames = []; + + if ($nbAnswers < 1) { + $nbAnswers = 1; + Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer')); + } + + // Can be more options + $optionData = Question::readQuestionOption($this->id, $courseId); + + for ($i = 1; $i <= $nbAnswers; ++$i) { + $renderer->setElementTemplate( + '', + 'correct['.$i.']' + ); + $renderer->setElementTemplate( + '', + 'counter['.$i.']' + ); + $renderer->setElementTemplate( + '', + 'answer['.$i.']' + ); + $renderer->setElementTemplate( + '', + 'comment['.$i.']' + ); + + $answerNumber = $form->addElement('text', 'counter['.$i.']', null, 'value="'.$i.'"'); + $answerNumber->freeze(); + + if (is_object($answer)) { + $defaults['answer['.$i.']'] = $answer->answer[$i]; + $defaults['comment['.$i.']'] = $answer->comment[$i]; + $defaults['weighting['.$i.']'] = float_format($answer->weighting[$i], 1); + + $correct = $answer->correct[$i]; + $defaults['correct['.$i.']'] = $correct; + + $j = 1; + if (!empty($optionData)) { + foreach ($optionData as $id => $data) { + $form->addElement('radio', 'correct['.$i.']', null, null, $id); + $j++; + if ($j == 3) { + break; + } + } + } + } else { + $form->addElement('radio', 'correct['.$i.']', null, null, 1); + $form->addElement('radio', 'correct['.$i.']', null, null, 2); + + $defaults['answer['.$i.']'] = ''; + $defaults['comment['.$i.']'] = ''; + $defaults['correct['.$i.']'] = ''; + } + + $boxesNames[] = 'correct['.$i.']'; + $form->addElement( + 'html_editor', + 'answer['.$i.']', + null, + 'style="vertical-align:middle"', + ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']); + $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required'); + + // show comment when feedback is enable + if ($objEx->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_EXAM) { + $form->addElement('html_editor', + 'comment['.$i.']', + null, + 'style="vertical-align:middle"', + ['ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100']); + } + $form->addElement('html', ''); + } + + $form->addElement('html', '
' + .get_lang('Number') + .'' + .get_lang('True') + .'' + .get_lang('False') + .'' + .get_lang('Answer') + .''.get_lang('Comment').'
{error}
{element}
{error}
{element}
{error}
{element}
{error}
{element}
'); + $form->addElement('html', '
'); + + // 3 scores + $form->addElement('text', 'option[1]', get_lang('Correct'), ['class' => 'span1', 'value' => '1']); + $form->addElement('text', 'option[2]', get_lang('Wrong'), ['class' => 'span1', 'value' => '-0.5']); + + $form->addElement('hidden', 'option[3]', 0); + + $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required'); + $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required'); + + $form->addElement('html', ''); + $form->addElement('hidden', 'options_count', 3); + $form->addElement('html', '


'); + + //Extra values True, false, Dont known + if (!empty($this->extra)) { + $scores = explode(':', $this->extra); + if (!empty($scores)) { + for ($i = 1; $i <= 3; $i++) { + $defaults['option['.$i.']'] = $scores[$i - 1]; + } + } + } + + global $text, $class; + if ($objEx->edit_exercise_in_lp == true) { + $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'), 'class="btn minus"'); + $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'), 'class="btn plus"'); + $form->addElement('submit', 'submitQuestion', $text, 'class="'.$class.'"'); + } + $renderer->setElementTemplate('{element} ', 'lessAnswers'); + $renderer->setElementTemplate('{element} ', 'submitQuestion'); + $renderer->setElementTemplate('{element} ', 'moreAnswers'); + $form->addElement('html', '
'); + $defaults['correct'] = $correct; + + if (!empty($this->id)) { + $form->setDefaults($defaults); + } else { + //if ($this -> isContent == 1) { + $form->setDefaults($defaults); + //} + } + $form->setConstants(['nb_answers' => $nbAnswers]); + } + + /** + * abstract function which creates the form to create / edit the answers of the question. + * + * @param FormValidator $form + * @param Exercise $exercise + */ + public function processAnswersCreation($form, $exercise) + { + $questionWeighting = $nbrGoodAnswers = 0; + $objAnswer = new Answer($this->id); + $nbAnswers = $form->getSubmitValue('nb_answers'); + + $courseId = api_get_course_int_id(); + + $correct = []; + $options = Question::readQuestionOption($this->id, $courseId); + + if (!empty($options)) { + foreach ($options as $optionData) { + $id = $optionData['id']; + unset($optionData['id']); + Question::updateQuestionOption($id, $optionData, $courseId); + } + } else { + for ($i = 1; $i <= 8; $i++) { + $lastId = Question::saveQuestionOption($this->id, $this->options[$i], $courseId, $i); + $correct[$i] = $lastId; + } + } + + /* Getting quiz_question_options (true, false, doubt) because + it's possible that there are more options in the future */ + + $newOptions = Question::readQuestionOption($this->id, $courseId); + + $sortedByPosition = []; + foreach ($newOptions as $item) { + $sortedByPosition[$item['position']] = $item; + } + + /* Saving quiz_question.extra values that has the correct scores of + the true, false, doubt options registered in this format + XX:YY:ZZZ where XX is a float score value. */ + $extraValues = []; + + for ($i = 1; $i <= 3; $i++) { + $score = trim($form->getSubmitValue('option['.$i.']')); + $extraValues[] = $score; + } + $this->setExtra(implode(':', $extraValues)); + + for ($i = 1; $i <= $nbAnswers; $i++) { + $answer = trim($form->getSubmitValue('answer['.$i.']')); + $comment = trim($form->getSubmitValue('comment['.$i.']')); + $goodAnswer = trim($form->getSubmitValue('correct['.$i.']')); + if (empty($options)) { + //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered + $goodAnswer = $sortedByPosition[$goodAnswer]['id']; + } + $questionWeighting += $extraValues[0]; //By default 0 has the correct answers + $objAnswer->createAnswer($answer, $goodAnswer, $comment, '', $i); + } + + // saves the answers into the data base + $objAnswer->save(); + + // sets the total weighting of the question + $this->updateWeighting($questionWeighting); + $this->save($exercise); + } + + /** + * @param int $feedbackType + * @param int $counter + * @param float $score + * + * @return null|string + */ + public function return_header($feedbackType = null, $counter = null, $score = null) + { + $header = parent::return_header($feedbackType, $counter, $score); + $header .= '' + ; + if ($feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { + $header .= ''; + } else { + $header .= ''; + } + $header .= ''; + + return $header; + } + + /** + * Method to recovery color to show by precision of the student's answer. + * + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * + * @return string + */ + public function getColorResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) + { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) { + return '#088A08'; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return '#A9F5A9'; + } + if ($studentDegreeChoicePosition == 3) { + return '#FFFFFF'; + } + } else { + if ($studentDegreeChoicePosition >= 6) { + return '#FE2E2E'; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return '#F6CECE'; + } + if ($studentDegreeChoicePosition == 3) { + return '#FFFFFF'; + } + } + } + + /** + * Return the color code for student answer. + * + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * + * @return int + */ + public function getStatusResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) + { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) { + return self::LEVEL_DARKGREEN; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return self::LEVEL_LIGHTGREEN; + } + if ($studentDegreeChoicePosition == 3) { + return self::LEVEL_WHITE; + } + } else { + if ($studentDegreeChoicePosition >= 6) { + return self::LEVEL_DARKRED; + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return self::LEVEL_LIGHTRED; + } + if ($studentDegreeChoicePosition == 3) { + return self::LEVEL_WHITE; + } + } + } + + /** + * Method to recovery lable for codes colors. + * + * @param $studentAnwser + * @param $expectedAnswer + * @param $studentDegreeChoicePosition + * + * @return string + */ + public function getCodeResponse($studentAnwser, $expectedAnswer, $studentDegreeChoicePosition) + { + $checkResult = ($studentAnwser == $expectedAnswer) ? true : false; + if ($checkResult) { + if ($studentDegreeChoicePosition >= 6) { + return get_lang('langVerySure'); + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return get_lang('langPrettySur'); + } + if ($studentDegreeChoicePosition == 3) { + return get_lang('langIgnorance'); + } + } else { + if ($studentDegreeChoicePosition >= 6) { + return get_lang('langVeryUnsure'); + } + if ($studentDegreeChoicePosition >= 4 && $studentDegreeChoicePosition <= 5) { + return get_lang('langUnsure'); + } + if ($studentDegreeChoicePosition == 3) { + return get_lang('langIgnorance'); + } + } + } + + /** + * Method to show the code color and his meaning for the test result. + */ + public static function showColorCode() + { ?> -
' + .get_lang("Choice") + .'' + .get_lang("ExpectedChoice") + .'' + .get_lang("Answer") + .'' + .get_lang("YourDegreeOfCertainty") + .' '.get_lang("Comment").' 
+
- + - + - + - + - +
  +   + :
  +   + :
  +   + :
  +   + :
  +   + : @@ -468,160 +479,165 @@ public static function showColorCode()

- gather_questions_categories == 1) { // original - $groupCategoriesByBracket = true; - } else { - $groupCategoriesByBracket = false; - } - - if ($groupCategoriesByBracket) { - $scoreList = []; - $categoryPrefixList = []; // categoryPrefix['Math'] = firstCategoryId for this prefix - // rebuild $scoreList factirizing datas with caregory prefix - foreach ($scoreListAll as $categoryId => $scoreListForCategory) { - $objCategory = new Testcategory(); - $objCategoryNum = $objCategory->getCategory($categoryId); - preg_match("/^\[([^]]+)\]/", $objCategoryNum->name, $matches); - - if (count($matches) > 1) { - // check if we have already see this prefix - if (array_key_exists($matches[1], $categoryPrefixList)) { - // add the result color for this entry - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKGREEN] += $scoreListForCategory[self::LEVEL_DARKGREEN]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTGREEN] += $scoreListForCategory[self::LEVEL_LIGHTGREEN]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_WHITE] += $scoreListForCategory[self::LEVEL_WHITE]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTRED] += $scoreListForCategory[self::LEVEL_LIGHTRED]; - $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKRED] += $scoreListForCategory[self::LEVEL_DARKRED]; - } else { - $categoryPrefixList[$matches[1]] = $categoryId; - $scoreList[$categoryId] = $scoreListAll[$categoryId]; - } - } else { - // dont matche the prefix '[math] Math category' - $scoreList[$categoryId] = $scoreListAll[$categoryId]; - } - } - } else { - $scoreList = $scoreListAll; - } - - // get the max height of item to have each table the same height if displayed side by side - foreach ($scoreList as $categoryId => $scoreListForCategory) { - $testCategorie = new TestCategory(); - $categorieQuestionName = $testCategorie->getCategory($categoryId)->name; - list($null, $height) = self::displayDegreeChart( - $scoreListForCategory, - 300, - '', - 1, - 0, - false, - true, - groupCategoriesByBracket - ); - if ($height > $maxHeight) { - $maxHeight = $height; - } - } - - if (count($scoreList) > 1) { - $boxWidth = $sizeRatio * 300 * 2 + 54; - } else { - $boxWidth = $sizeRatio * 300 + 54; - } - - $html = '
'; - $html .= '

'.$title.'

'; - - // get the html of items - $i = 0; - foreach ($scoreList as $categoryId => $scoreListForCategory) { - $oCategory = new Testcategory(); - $categorieQuestionName = $oCategory->getCategory($categoryId)->name; - - if ($categorieQuestionName == '') { - $categoryName = get_lang('NonCategory'); - } else { - $categoryName = $oCategory->name; - } - - $html .= '
'; - $html .= self::displayDegreeChart( - $scoreListForCategory, - 300, - $categoryName, - 1, - $maxHeight, - false, - false, - $groupCategoriesByBracket - ); - $html .= '
'; - - if ($i == 1) { - $html .= '
 
'; - $i = 0; - } else { - $i++; - } - } - - return $html.'
 
'; - } - - /** - * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions. - * - * @param $scoreList - * @param int $sizeRatio - * - * @return string - */ - public static function displayDegreeChart( - $scoreList, - $widthTable, - $title = '', - $sizeRatio = 1, - $minHeight = 0, - $displayExplanationText = true, - $returnHeight = false, - $groupCategoriesByBracket = false, - $numberOfQuestions = 0 - ) { - $topAndBottomMargin = 10; - - $colorList = [self::LEVEL_DARKRED, - self::LEVEL_LIGHTRED, - self::LEVEL_WHITE, - self::LEVEL_LIGHTGREEN, - self::LEVEL_DARKGREEN, - ]; - - // get total attempt number - $highterColorHeight = 0; - - foreach ($scoreList as $color => $number) { - if ($number > $highterColorHeight) { - $highterColorHeight = $number; - } - } - - $totalAttemptNumber = $numberOfQuestions; - - $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2; - if ($verticalLineHeight < $minHeight) { - $minHeightCorrection = $minHeight - $verticalLineHeight; - $verticalLineHeight += $minHeightCorrection; - } - - // draw chart + gather_questions_categories == 1) { // original + $groupCategoriesByBracket = true; + } else { + $groupCategoriesByBracket = false; + } + + if ($groupCategoriesByBracket) { + $scoreList = []; + $categoryPrefixList = []; // categoryPrefix['Math'] = firstCategoryId for this prefix + // rebuild $scoreList factirizing datas with caregory prefix + foreach ($scoreListAll as $categoryId => $scoreListForCategory) { + $objCategory = new Testcategory(); + $objCategoryNum = $objCategory->getCategory($categoryId); + preg_match("/^\[([^]]+)\]/", $objCategoryNum->name, $matches); + + if (count($matches) > 1) { + // check if we have already see this prefix + if (array_key_exists($matches[1], $categoryPrefixList)) { + // add the result color for this entry + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKGREEN] += + $scoreListForCategory[self::LEVEL_DARKGREEN]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTGREEN] += + $scoreListForCategory[self::LEVEL_LIGHTGREEN]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_WHITE] += + $scoreListForCategory[self::LEVEL_WHITE]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_LIGHTRED] += + $scoreListForCategory[self::LEVEL_LIGHTRED]; + $scoreList[$categoryPrefixList[$matches[1]]][self::LEVEL_DARKRED] += + $scoreListForCategory[self::LEVEL_DARKRED]; + } else { + $categoryPrefixList[$matches[1]] = $categoryId; + $scoreList[$categoryId] = $scoreListAll[$categoryId]; + } + } else { + // dont matche the prefix '[math] Math category' + $scoreList[$categoryId] = $scoreListAll[$categoryId]; + } + } + } else { + $scoreList = $scoreListAll; + } + + // get the max height of item to have each table the same height if displayed side by side + foreach ($scoreList as $categoryId => $scoreListForCategory) { + $testCategorie = new TestCategory(); + $categorieQuestionName = $testCategorie->getCategory($categoryId)->name; + list($null, $height) = self::displayDegreeChart( + $scoreListForCategory, + 300, + '', + 1, + 0, + false, + true, + groupCategoriesByBracket + ); + if ($height > $maxHeight) { + $maxHeight = $height; + } + } + + if (count($scoreList) > 1) { + $boxWidth = $sizeRatio * 300 * 2 + 54; + } else { + $boxWidth = $sizeRatio * 300 + 54; + } + + $html = '
'; + $html .= '

'.$title.'

'; + + // get the html of items + $i = 0; + foreach ($scoreList as $categoryId => $scoreListForCategory) { + $oCategory = new Testcategory(); + $categorieQuestionName = $oCategory->getCategory($categoryId)->name; + + if ($categorieQuestionName == '') { + $categoryName = get_lang('NonCategory'); + } else { + $categoryName = $oCategory->name; + } + + $html .= '
'; + $html .= self::displayDegreeChart( + $scoreListForCategory, + 300, + $categoryName, + 1, + $maxHeight, + false, + false, + $groupCategoriesByBracket + ); + $html .= '
'; + + if ($i == 1) { + $html .= '
 
'; + $i = 0; + } else { + $i++; + } + } + + return $html.'
 
'; + } + + /** + * Return HTML code for the $scoreList of MultipleAnswerTrueFalseDegreeCertainty questions. + * + * @param $scoreList + * @param int $sizeRatio + * + * @return string + */ + public static function displayDegreeChart( + $scoreList, + $widthTable, + $title = '', + $sizeRatio = 1, + $minHeight = 0, + $displayExplanationText = true, + $returnHeight = false, + $groupCategoriesByBracket = false, + $numberOfQuestions = 0 + ) { + $topAndBottomMargin = 10; + + $colorList = [self::LEVEL_DARKRED, + self::LEVEL_LIGHTRED, + self::LEVEL_WHITE, + self::LEVEL_LIGHTGREEN, + self::LEVEL_DARKGREEN, + ]; + + // get total attempt number + $highterColorHeight = 0; + + foreach ($scoreList as $color => $number) { + if ($number > $highterColorHeight) { + $highterColorHeight = $number; + } + } + + $totalAttemptNumber = $numberOfQuestions; + + $verticalLineHeight = $highterColorHeight * $sizeRatio * 2 + 122 + $topAndBottomMargin * 2; + if ($verticalLineHeight < $minHeight) { + $minHeightCorrection = $minHeight - $verticalLineHeight; + $verticalLineHeight += $minHeightCorrection; + } + + // draw chart $html = ''; - - if ($groupCategoriesByBracket) { - $title = api_preg_replace("/[^]]*$/", "", $title); - $title = ucfirst(api_preg_replace("/[\[\]]/", "", $title)); - } - - $affiche = (strpos($title, "ensemble") > 0) ? - $title."
($totalAttemptNumber questions)" : - $title; - $textSize = ( - strpos($title, "ensemble") > 0 || - strpos($title, "votre dernier résultat à ce test") > 0 - ) ? 100 : 80; - - if ($displayExplanationText) { - // global chart - $classGlobalChart = "globalChart"; - } else { - $classGlobalChart = ""; - } - - $html .= '' - ; - $html .= '' - ; - - $nbResponsesInc = (isset($scoreList[4]) || isset($scoreList[5])) ? $scoreList[4] + $scoreList[5] : 0; - $nbResponsesIng = (isset($scoreList[3])) ? $scoreList[3] : 0; - $nbResponsesCor = (isset($scoreList[1]) || isset($scoreList[2])) ? $scoreList[1] + $scoreList[2] : 0; - - $colWidth = $widthTable / 5; - + '; + + if ($groupCategoriesByBracket) { + $title = api_preg_replace("/[^]]*$/", "", $title); + $title = ucfirst(api_preg_replace("/[\[\]]/", "", $title)); + } + + $affiche = (strpos($title, "ensemble") > 0) ? + $title."
($totalAttemptNumber questions)" : + $title; + $textSize = ( + strpos($title, "ensemble") > 0 || + strpos($title, "votre dernier résultat à ce test") > 0 + ) ? 100 : 80; + + if ($displayExplanationText) { + // global chart + $classGlobalChart = "globalChart"; + } else { + $classGlobalChart = ""; + } + + $html .= '
' - .$affiche - .'
' + ; + $html .= '' + ; + + $nbResponsesInc = (isset($scoreList[4]) || isset($scoreList[5])) ? $scoreList[4] + $scoreList[5] : 0; + $nbResponsesIng = (isset($scoreList[3])) ? $scoreList[3] : 0; + $nbResponsesCor = (isset($scoreList[1]) || isset($scoreList[2])) ? $scoreList[1] + $scoreList[2] : 0; + + $colWidth = $widthTable / 5; + $html .= ' - '; - $html .= ''; - - foreach ($colorList as $i => $color) { - if (array_key_exists($color, $scoreList)) { - $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom - } else { - $scoreOnBottom = 0; - } - - $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2; - - if ($i == 1 || $i == 2) { - $html .= ''; - } - - $html .= ''; - - if ($displayExplanationText) { - // affichage texte histogramme - $explainHistoList = [ - 'langVeryUnsure', - 'langUnsure', - 'langIgnorance', - 'langPrettySur', - 'langVerySure', ]; - $html .= ''; - $i = 0; - foreach ($explainHistoList as $explain) { - if ($i == 1 || $i == 2) { - $class = "borderRight"; - } else { - $class = ""; - } - $html .= ''; - $i++; - } - $html .= ''; - } - - $html .= '
' + .$affiche + .'
'. + style="width:'.($colWidth * 2).'px; font-size:'.$textSize.'%;">'. get_lang('langWrongsAnswers').' : '.$nbResponsesInc.' '. + style="width:'.$colWidth.'px; font-size :'.$textSize.'%;">'. get_lang('langIgnoranceAnswers').' : '.$nbResponsesIng.' '. + style="width:'.($colWidth * 2).'px; font-size:'.$textSize.'%;">'. get_lang('langCorrectsAnswers').' : '.$nbResponsesCor.'
' - ; - } else { - $html .= '' - ; - } - $html .= '
' - .$scoreOnBottom - .'
 
' - ; - $html .= '
' - ; - $html .= get_lang($explain); - $html .= '
'; - - if ($returnHeight) { - return [$html, $verticalLineHeight]; - } else { - return $html; - } - } - - /** - * return previous attempt id for this test for student, 0 if no previous attempt. - * - * @param $exeId - * - * @return int - */ - public static function getPreviousAttemptId($exeId) - { - $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + '; + $html .= ''; + + foreach ($colorList as $i => $color) { + if (array_key_exists($color, $scoreList)) { + $scoreOnBottom = $scoreList[$color]; // height of the colored area on the bottom + } else { + $scoreOnBottom = 0; + } + + $sizeOnBottom = $scoreOnBottom * $sizeRatio * 2; + + if ($i == 1 || $i == 2) { + $html .= '' + ; + } else { + $html .= '' + ; + } + $html .= '
' + .$scoreOnBottom + .'
 
' + ; + $html .= ''; + } + + $html .= ''; + + if ($displayExplanationText) { + // affichage texte histogramme + $explainHistoList = [ + 'langVeryUnsure', + 'langUnsure', + 'langIgnorance', + 'langPrettySur', + 'langVerySure', ]; + $html .= ''; + $i = 0; + foreach ($explainHistoList as $explain) { + if ($i == 1 || $i == 2) { + $class = "borderRight"; + } else { + $class = ""; + } + $html .= '' + ; + $html .= get_lang($explain); + $html .= ''; + $i++; + } + $html .= ''; + } + + $html .= ''; + + if ($returnHeight) { + return [$html, $verticalLineHeight]; + } else { + return $html; + } + } + + /** + * return previous attempt id for this test for student, 0 if no previous attempt. + * + * @param $exeId + * + * @return int + */ + public static function getPreviousAttemptId($exeId) + { + $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); $sql = "SELECT * FROM $tblTrackEExercise - WHERE exe_id = ".intval($exeId); - $res = Database::query($sql); - - if (Database::num_rows($res) == 0) { - // if we cannot find the exe_id - return 0; - } - - $data = Database::fetch_assoc($res); - $courseCode = $data['exe_cours_id']; - $exerciseId = $data['exe_exo_id']; - $userId = $data['exe_user_id']; - $attemptDate = $data['exe_date']; - - if ($attemptDate == "0000-00-00 00:00:00") { - // incomplete attempt, close it before continue - return 0; - } - - // look for previous attempt + WHERE exe_id = ".intval($exeId); + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + // if we cannot find the exe_id + return 0; + } + + $data = Database::fetch_assoc($res); + $courseCode = $data['exe_cours_id']; + $exerciseId = $data['exe_exo_id']; + $userId = $data['exe_user_id']; + $attemptDate = $data['exe_date']; + + if ($attemptDate == "0000-00-00 00:00:00") { + // incomplete attempt, close it before continue + return 0; + } + + // look for previous attempt $sql = "SELECT * FROM $tblTrackEExercise WHERE c_id = '".$courseCode."' @@ -890,314 +906,315 @@ public static function getPreviousAttemptId($exeId) AND status = '' AND exe_date > '0000-00-00 00:00:00' AND exe_date < '".$attemptDate."' - ORDER BY exe_date DESC"; - - $res = Database::query($sql); - - if (Database::num_rows($res) == 0) { - // no previous attempt - return 0; - } - - $data = Database::fetch_assoc($res); - - return $data['exe_id']; - } - - /** - * return an array of number of answer color for exe attempt for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY - * e.g. - * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0]. - * - * @param $exeId - * - * @return array - */ - public static function getColorNumberListForAttempt($exeId) - { - $result = [self::LEVEL_DARKGREEN => 0, - self::LEVEL_LIGHTGREEN => 0, - self::LEVEL_WHITE => 0, - self::LEVEL_LIGHTRED => 0, - self::LEVEL_DARKRED => 0, - ]; - - $attemptInfoList = self::getExerciseAttemptInfo($exeId); - - foreach ($attemptInfoList as $i => $attemptInfo) { - $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); - $oQuestion->read($attemptInfo['question_id']); - if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { - $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); - if ($answerColor) { - $result[$answerColor]++; - } - } - } - - return $result; - } - - /** - * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY - * for each question category. - * - * e.g. - * [ - * (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12] - * (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8] - * (categoryId=)0 => [LEVEL_DARKGREEN => 1, LEVEL_LIGHTGREEN => 2, LEVEL_WHITE => 6, LEVEL_LIGHTRED => 1, LEVEL_DARKTRED => 9] - * ] - * - * @param $exeId - * - * @return array - */ - public static function getColorNumberListForAttemptByCategory($exeId) - { - $result = []; - $attemptInfoList = self::getExerciseAttemptInfo($exeId); - - foreach ($attemptInfoList as $i => $attemptInfo) { - $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); - $oQuestion->read($attemptInfo['question_id']); - if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { - $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']); - - if (!array_key_exists($questionCategory, $result)) { - $result[$questionCategory] = []; - } - - $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); - if ($answerColor) { - $result[$questionCategory][$answerColor]++; - } - } - } - - return $result; - } - - /** - * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false. - * - * @param $exeId - * @param $questionId - * @param $position - * - * @return bool - */ - public static function getAnswerColor($exeId, $questionId, $position) - { - $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position); - - if (count($attemptInfoList) != 1) { - // havent got the answer - return 0; - } - - $answerCodes = $attemptInfoList[0]['answer']; - - // student answer - $splitAnswer = preg_split("/:/", $answerCodes); - // get correct answer option id - $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]); - if ($correctAnswerOptionId == 0) { - // error returning the correct answer option id - return 0; - } - - // get student answer option id - $studentAnswerOptionId = $splitAnswer[1]; - - // we got the correct answer option id, let's compare ti with the student answer - $percentage = self::getPercentagePosition($splitAnswer[2]); - if ($studentAnswerOptionId == $correctAnswerOptionId) { - // yeah, student got correct answer - switch ($percentage) { - case 3: - return self::LEVEL_WHITE; - case 4: - case 5: - return self::LEVEL_LIGHTGREEN; - case 6: - case 7: - case 8: - return self::LEVEL_DARKGREEN; - default: - return 0; - } - } else { - // bummer, wrong answer dude - switch ($percentage) { - case 3: - return self::LEVEL_WHITE; - case 4: - case 5: - return self::LEVEL_LIGHTRED; - case 6: - case 7: - case 8: - return self::LEVEL_DARKRED; - default: - return 0; - } - } - } - - /** - * Return the position of certitude %age choose by student. - * - * @param $optionId - * - * @return int - */ - public static function getPercentagePosition($optionId) - { - $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION); - $courseId = api_get_course_int_id(); + ORDER BY exe_date DESC"; + + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + // no previous attempt + return 0; + } + + $data = Database::fetch_assoc($res); + + return $data['exe_id']; + } + + /** + * return an array of number of answer color for exe attempt + * for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + * e.g. + * [LEVEL_DARKGREEN => 3, LEVEL_LIGHTGREEN => 0, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12, LEVEL_DARKTRED => 0]. + * + * @param $exeId + * + * @return array + */ + public static function getColorNumberListForAttempt($exeId) + { + $result = [self::LEVEL_DARKGREEN => 0, + self::LEVEL_LIGHTGREEN => 0, + self::LEVEL_WHITE => 0, + self::LEVEL_LIGHTRED => 0, + self::LEVEL_DARKRED => 0, + ]; + + $attemptInfoList = self::getExerciseAttemptInfo($exeId); + + foreach ($attemptInfoList as $i => $attemptInfo) { + $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); + $oQuestion->read($attemptInfo['question_id']); + if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); + if ($answerColor) { + $result[$answerColor]++; + } + } + } + + return $result; + } + + /** + * return an array of number of color for question type = MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY + * for each question category. + * + * e.g. + * [ + * (categoryId=)5 => [LEVEL_DARKGREEN => 3, LEVEL_WHITE => 5, LEVEL_LIGHTRED => 12] + * (categoryId=)2 => [LEVEL_DARKGREEN => 8, LEVEL_LIGHTRED => 2, LEVEL_DARKTRED => 8] + * (categoryId=)0 => [LEVEL_DARKGREEN => 1, LEVEL_LIGHTGREEN => 2, LEVEL_WHITE => 6, LEVEL_LIGHTRED => 1, LEVEL_DARKTRED => 9] + * ] + * + * @param $exeId + * + * @return array + */ + public static function getColorNumberListForAttemptByCategory($exeId) + { + $result = []; + $attemptInfoList = self::getExerciseAttemptInfo($exeId); + + foreach ($attemptInfoList as $i => $attemptInfo) { + $oQuestion = new MultipleAnswerTrueFalseDegreeCertainty(); + $oQuestion->read($attemptInfo['question_id']); + if ($oQuestion->type == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) { + $questionCategory = Testcategory::getCategoryForQuestion($attemptInfo['question_id']); + + if (!array_key_exists($questionCategory, $result)) { + $result[$questionCategory] = []; + } + + $answerColor = self::getAnswerColor($exeId, $attemptInfo['question_id'], $attemptInfo['position']); + if ($answerColor) { + $result[$questionCategory][$answerColor]++; + } + } + } + + return $result; + } + + /** + * Return true if answer of $exeId, $questionId, $position is correct, otherwise return false. + * + * @param $exeId + * @param $questionId + * @param $position + * + * @return bool + */ + public static function getAnswerColor($exeId, $questionId, $position) + { + $attemptInfoList = self::getExerciseAttemptInfo($exeId, $questionId, $position); + + if (count($attemptInfoList) != 1) { + // havent got the answer + return 0; + } + + $answerCodes = $attemptInfoList[0]['answer']; + + // student answer + $splitAnswer = preg_split("/:/", $answerCodes); + // get correct answer option id + $correctAnswerOptionId = self::getCorrectAnswerOptionId($splitAnswer[0]); + if ($correctAnswerOptionId == 0) { + // error returning the correct answer option id + return 0; + } + + // get student answer option id + $studentAnswerOptionId = $splitAnswer[1]; + + // we got the correct answer option id, let's compare ti with the student answer + $percentage = self::getPercentagePosition($splitAnswer[2]); + if ($studentAnswerOptionId == $correctAnswerOptionId) { + // yeah, student got correct answer + switch ($percentage) { + case 3: + return self::LEVEL_WHITE; + case 4: + case 5: + return self::LEVEL_LIGHTGREEN; + case 6: + case 7: + case 8: + return self::LEVEL_DARKGREEN; + default: + return 0; + } + } else { + // bummer, wrong answer dude + switch ($percentage) { + case 3: + return self::LEVEL_WHITE; + case 4: + case 5: + return self::LEVEL_LIGHTRED; + case 6: + case 7: + case 8: + return self::LEVEL_DARKRED; + default: + return 0; + } + } + } + + /** + * Return the position of certitude %age choose by student. + * + * @param $optionId + * + * @return int + */ + public static function getPercentagePosition($optionId) + { + $tblAnswerOption = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION); + $courseId = api_get_course_int_id(); $sql = "SELECT position FROM $tblAnswerOption WHERE c_id = ".intval($courseId)." - AND id = ".intval($optionId); - $res = Database::query($sql); - - if (Database::num_rows($res) == 0) { - return 0; - } - - $data = Database::fetch_assoc($res); - - return $data['position']; - } - - /** - * return the correct id from c_quiz_question_option for question idAuto. - * - * @param $idAuto - * - * @return int - */ - public static function getCorrectAnswerOptionId($idAuto) - { - $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER); - $courseId = api_get_course_int_id(); + AND id = ".intval($optionId); + $res = Database::query($sql); + + if (Database::num_rows($res) == 0) { + return 0; + } + + $data = Database::fetch_assoc($res); + + return $data['position']; + } + + /** + * return the correct id from c_quiz_question_option for question idAuto. + * + * @param $idAuto + * + * @return int + */ + public static function getCorrectAnswerOptionId($idAuto) + { + $tblAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER); + $courseId = api_get_course_int_id(); $sql = "SELECT correct FROM $tblAnswer WHERE c_id = ".intval($courseId)." - AND id_auto = ".intval($idAuto); - - $res = Database::query($sql); - $data = Database::fetch_assoc($res); - if (Database::num_rows($res) > 0) { - return $data['correct']; - } else { - return 0; - } - } - - /** - * return an array of exe info from track_e_attempt. - * - * @param $exeId - * @param int $questionId - * @param int $position - * - * @return array - */ - public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1) - { - $result = []; - $and = ''; - - if ($questionId >= 0) { - $and .= " AND question_id = ".intval($questionId); - } - if ($position >= 0) { - $and .= " AND position = ".intval($position); - } - - $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); - $cId = api_get_course_int_id(); + AND id_auto = ".intval($idAuto); + + $res = Database::query($sql); + $data = Database::fetch_assoc($res); + if (Database::num_rows($res) > 0) { + return $data['correct']; + } else { + return 0; + } + } + + /** + * return an array of exe info from track_e_attempt. + * + * @param $exeId + * @param int $questionId + * @param int $position + * + * @return array + */ + public static function getExerciseAttemptInfo($exeId, $questionId = -1, $position = -1) + { + $result = []; + $and = ''; + + if ($questionId >= 0) { + $and .= " AND question_id = ".intval($questionId); + } + if ($position >= 0) { + $and .= " AND position = ".intval($position); + } + + $tblExeAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); + $cId = api_get_course_int_id(); $sql = "SELECT * FROM $tblExeAttempt WHERE c_id = $cId AND exe_id = $exeId - $and"; - - $res = Database::query($sql); - while ($data = Database::fetch_assoc($res)) { - $result[] = $data; - } - - return $result; - } - - public static function getNumberOfQuestionsForExeId($exeId) - { - $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); + $and"; + + $res = Database::query($sql); + while ($data = Database::fetch_assoc($res)) { + $result[] = $data; + } + + return $result; + } + + public static function getNumberOfQuestionsForExeId($exeId) + { + $tableTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); $sql = "SELECT exe_exo_id FROM $tableTrackEExercise - WHERE exe_id=".intval($exeId); - $res = Database::query($sql); - $data = Database::fetch_assoc($res); - $exerciseId = $data['exe_exo_id']; - - $objectExercise = new Exercise(); - $objectExercise->read($exerciseId); - - return $objectExercise->get_count_question_list(); - } - - /** - * Display student chart results for these question types. - * - * @param $exeId - * - * @return string - */ - public static function displayStudentsChartResults($exeId, $objExercice) - { - $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId); - - $globalScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt($exeId); - $html = MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( - $globalScoreList, - 600, - get_lang('ResultTest'), - 2, - 0, - true, - false, - false, - $numberOfQuestions - ) - ."
" - ; - - $previousAttemptId = MultipleAnswerTrueFalseDegreeCertainty::getPreviousAttemptId($exeId); - if ($previousAttemptId > 0) { - $previousAttemptScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt( - $previousAttemptId - ); - $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( - $previousAttemptScoreList, - 600, - get_lang('CompareLastResult'), - 2 - ) - ."
" - ; - } - - $categoryScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttemptByCategory($exeId); - $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChartByCategory( - $categoryScoreList, - get_lang('ResultsbyDiscipline'), - 1, $objExercice - ) - ."
" - ; - - return $html; - } - } + WHERE exe_id=".intval($exeId); + $res = Database::query($sql); + $data = Database::fetch_assoc($res); + $exerciseId = $data['exe_exo_id']; + + $objectExercise = new Exercise(); + $objectExercise->read($exerciseId); + + return $objectExercise->get_count_question_list(); + } + + /** + * Display student chart results for these question types. + * + * @param $exeId + * + * @return string + */ + public static function displayStudentsChartResults($exeId, $objExercice) + { + $numberOfQuestions = self::getNumberOfQuestionsForExeId($exeId); + + $globalScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt($exeId); + $html = MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( + $globalScoreList, + 600, + get_lang('ResultTest'), + 2, + 0, + true, + false, + false, + $numberOfQuestions + ) + ."
" + ; + + $previousAttemptId = MultipleAnswerTrueFalseDegreeCertainty::getPreviousAttemptId($exeId); + if ($previousAttemptId > 0) { + $previousAttemptScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttempt( + $previousAttemptId + ); + $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChart( + $previousAttemptScoreList, + 600, + get_lang('CompareLastResult'), + 2 + ) + ."
" + ; + } + + $categoryScoreList = MultipleAnswerTrueFalseDegreeCertainty::getColorNumberListForAttemptByCategory($exeId); + $html .= MultipleAnswerTrueFalseDegreeCertainty::displayDegreeChartByCategory( + $categoryScoreList, + get_lang('ResultsbyDiscipline'), + 1, $objExercice + ) + ."
" + ; + + return $html; + } + } From c7cd686e8b85060f2168eeb0ce6e55179c1d0cf2 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Thu, 12 Jul 2018 14:59:27 +0200 Subject: [PATCH 19/30] Update exercise.lib.php --- main/inc/lib/exercise.lib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index 36923a6b7d4..4b5a8cbfb1f 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -4242,8 +4242,10 @@ public static function displayGroupMenu($in_name, $in_default, $in_onchange = "" $res .= ""; $currentCatId = $tabCategory["id"]; } - $res .= ""; + $res .= ""; } $res .= ""; From dbd1d8897b947e206878ec59e3a52d67afab81b7 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Thu, 12 Jul 2018 15:00:08 +0200 Subject: [PATCH 20/30] Update exercise_show_functions.lib.php --- main/inc/lib/exercise_show_functions.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/inc/lib/exercise_show_functions.lib.php b/main/inc/lib/exercise_show_functions.lib.php index 0f6c6674bff..82a3e439193 100755 --- a/main/inc/lib/exercise_show_functions.lib.php +++ b/main/inc/lib/exercise_show_functions.lib.php @@ -528,8 +528,8 @@ public static function displayMultipleAnswerTrueFalseDegreeCertainty( Date: Mon, 16 Jul 2018 13:23:06 +0200 Subject: [PATCH 21/30] Update exercise_show.php --- main/exercise/exercise_show.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/exercise/exercise_show.php b/main/exercise/exercise_show.php index 397b1434bb8..1238de1161d 100755 --- a/main/exercise/exercise_show.php +++ b/main/exercise/exercise_show.php @@ -223,7 +223,7 @@ function getFCK(vals, marksid) { } } - Date: Mon, 16 Jul 2018 13:25:15 +0200 Subject: [PATCH 22/30] Update exercise_submit.php --- main/exercise/exercise_submit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/exercise/exercise_submit.php b/main/exercise/exercise_submit.php index 17eb44f0751..41d97aaf63f 100755 --- a/main/exercise/exercise_submit.php +++ b/main/exercise/exercise_submit.php @@ -806,7 +806,7 @@ .html_entity_decode(get_lang('ResultAccomplishedTest')." \"".$objExercise->title."\""); // message sended to the student $message = get_lang('Dear').' '.$recipient_name.",

"; - //calcul du chemmin sans les script php + // build path without php script $url = $_SERVER['SCRIPT_NAME']; $pos = strripos($url, "/"); From 19b85a5b881cbc5685850515495ed27920253a7e Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 13:39:47 +0200 Subject: [PATCH 23/30] Update exercise_submit.php --- main/exercise/exercise_submit.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/main/exercise/exercise_submit.php b/main/exercise/exercise_submit.php index 41d97aaf63f..b7989b0ad23 100755 --- a/main/exercise/exercise_submit.php +++ b/main/exercise/exercise_submit.php @@ -804,14 +804,9 @@ $subject = "[".get_lang('DoNotReply')."] " .html_entity_decode(get_lang('ResultAccomplishedTest')." \"".$objExercise->title."\""); + // message sended to the student $message = get_lang('Dear').' '.$recipient_name.",

"; - // build path without php script - $url = $_SERVER['SCRIPT_NAME']; - $pos = strripos($url, "/"); - - $path = substr($url, 0, $pos); - $message .= get_lang('MessageQuestionCertainty'); $exerciseLink = "
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. From 033682627ac5400135aea0f58c46626534d4da8a Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 14:09:51 +0200 Subject: [PATCH 25/30] Update api.lib.php --- main/inc/lib/api.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 3934dddab98..649c82d844f 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -2182,7 +2182,8 @@ function api_format_course_array($course_data) null, null, null, - true + true, + false ); } $_course['course_image_large'] = $url_image; From 49fa4b7aab389668084161720b7e7d3c6db5c81d Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 14:10:38 +0200 Subject: [PATCH 26/30] Update api.lib.php --- main/inc/lib/api.lib.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 649c82d844f..56cfca2882a 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -2600,11 +2600,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 = "  ".Display::return_icon( - 'star.png', - get_lang('SessionSpecificResource'), - ['align' => 'absmiddle'], - ICON_SIZE_SMALL - ); + 'star.png', + get_lang('SessionSpecificResource'), + ['align' => 'absmiddle'], + ICON_SIZE_SMALL + ); } } From c239a3178947c98e1ce2bcf5259492fa60c94fcb Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 14:12:15 +0200 Subject: [PATCH 27/30] Update api.lib.php --- main/inc/lib/api.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 56cfca2882a..5b2ad9e4e1b 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -4895,7 +4895,7 @@ function api_get_visual_theme() $course_id = api_get_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_theme = api_get_course_setting('course_theme', $course_id); if (!empty($course_theme) && $course_theme != -1) { if (!empty($course_theme)) { From a34cb58532d4d011cc516bce97dc7f9a37cfb899 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 14:13:12 +0200 Subject: [PATCH 28/30] Update api.lib.php --- main/inc/lib/api.lib.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 5b2ad9e4e1b..9f167b1957e 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -5668,10 +5668,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. From 849e6f6b13d2cf0233aeb1f68617b999f9c3d546 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 14:13:49 +0200 Subject: [PATCH 29/30] Update api.lib.php --- main/inc/lib/api.lib.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 9f167b1957e..1306018625f 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -5693,12 +5693,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. From d6dcd17817954e4b187ba2cdf8c9693f26a144f4 Mon Sep 17 00:00:00 2001 From: pielRouge Date: Mon, 16 Jul 2018 14:18:30 +0200 Subject: [PATCH 30/30] Update api.lib.php --- main/inc/lib/api.lib.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main/inc/lib/api.lib.php b/main/inc/lib/api.lib.php index 1306018625f..7c94bbda52b 100644 --- a/main/inc/lib/api.lib.php +++ b/main/inc/lib/api.lib.php @@ -9036,18 +9036,18 @@ function api_float_val($number) * 3.141516 => 3.14 * 3,141516 => 3,14 * - * @todo WIP - * - * @param string $number number in iso code + * @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) +function api_number_format($number, $decimals = 0, $decimalSeparator = '.', $thousandSeparator = ',') { $number = api_float_val($number); - return number_format($number, $decimals); + return number_format($number, $decimals, $decimalSeparator, $thousandSeparator); } /**