Exemplo n.º 1
0
 /**
  * This function was originally found in the exercise_show.php
  * @param int       $exeId
  * @param int       $questionId
  * @param int       $choice the user selected
  * @param string    $from  function is called from 'exercise_show' or 'exercise_result'
  * @param array     $exerciseResultCoordinates the hotspot coordinates $hotspot[$question_id] = coordinates
  * @param bool      $saved_results save results in the DB or just show the reponse
  * @param bool      $from_database gets information from DB or from the current selection
  * @param bool      $show_result show results or not
  * @param int       $propagate_neg
  * @param array     $hotspot_delineation_result
  *
  * @todo    reduce parameters of this function
  * @return  string  html code
  */
 public function manage_answer($exeId, $questionId, $choice, $from = 'exercise_show', $exerciseResultCoordinates = array(), $saved_results = true, $from_database = false, $show_result = true, $propagate_neg = 0, $hotspot_delineation_result = array())
 {
     global $debug;
     //needed in order to use in the exercise_attempt() for the time
     global $learnpath_id, $learnpath_item_id;
     require_once api_get_path(LIBRARY_PATH) . 'geometry.lib.php';
     $feedback_type = $this->selectFeedbackType();
     $results_disabled = $this->selectResultsDisabled();
     if ($debug) {
         error_log("<------ manage_answer ------> ");
         error_log('exe_id: ' . $exeId);
         error_log('$from:  ' . $from);
         error_log('$saved_results: ' . intval($saved_results));
         error_log('$from_database: ' . intval($from_database));
         error_log('$show_result: ' . $show_result);
         error_log('$propagate_neg: ' . $propagate_neg);
         error_log('$exerciseResultCoordinates: ' . print_r($exerciseResultCoordinates, 1));
         error_log('$hotspot_delineation_result: ' . print_r($hotspot_delineation_result, 1));
         error_log('$learnpath_id: ' . $learnpath_id);
         error_log('$learnpath_item_id: ' . $learnpath_item_id);
         error_log('$choice: ' . print_r($choice, 1));
     }
     $extra_data = array();
     $final_overlap = 0;
     $final_missing = 0;
     $final_excess = 0;
     $overlap_color = 0;
     $missing_color = 0;
     $excess_color = 0;
     $threadhold1 = 0;
     $threadhold2 = 0;
     $threadhold3 = 0;
     $arrques = null;
     $arrans = null;
     $questionId = intval($questionId);
     $exeId = intval($exeId);
     $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
     $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
     // Creates a temporary Question object
     $course_id = $this->course_id;
     $objQuestionTmp = Question::read($questionId, $course_id);
     if ($objQuestionTmp === false) {
         return false;
     }
     $questionName = $objQuestionTmp->selectTitle();
     $questionWeighting = $objQuestionTmp->selectWeighting();
     $answerType = $objQuestionTmp->selectType();
     $quesId = $objQuestionTmp->selectId();
     $extra = $objQuestionTmp->extra;
     $next = 1;
     //not for now
     // Extra information of the question
     if (!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]));
     }
     $totalWeighting = 0;
     $totalScore = 0;
     // Destruction of the Question object
     unset($objQuestionTmp);
     // Construction of the Answer object
     $objAnswerTmp = new Answer($questionId);
     $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
     if ($debug) {
         error_log('Count of answers: ' . $nbrAnswers);
         error_log('$answerType: ' . $answerType);
     }
     if ($answerType == FREE_ANSWER || $answerType == ORAL_EXPRESSION || $answerType == CALCULATED_ANSWER) {
         $nbrAnswers = 1;
     }
     $nano = null;
     if ($answerType == ORAL_EXPRESSION) {
         $exe_info = Event::get_exercise_results_by_attempt($exeId);
         $exe_info = isset($exe_info[$exeId]) ? $exe_info[$exeId] : null;
         $params = array();
         $params['course_id'] = $course_id;
         $params['session_id'] = api_get_session_id();
         $params['user_id'] = isset($exe_info['exe_user_id']) ? $exe_info['exe_user_id'] : api_get_user_id();
         $params['exercise_id'] = isset($exe_info['exe_exo_id']) ? $exe_info['exe_exo_id'] : $this->id;
         $params['question_id'] = $questionId;
         $params['exe_id'] = isset($exe_info['exe_id']) ? $exe_info['exe_id'] : $exeId;
         $nano = new Nanogong($params);
         //probably this attempt came in an exercise all question by page
         if ($feedback_type == 0) {
             $nano->replace_with_real_exe($exeId);
         }
     }
     $user_answer = '';
     // Get answer list for matching
     $sql = "SELECT id_auto, id, answer\n                FROM {$table_ans}\n                WHERE c_id = {$course_id} AND question_id = {$questionId}";
     $res_answer = Database::query($sql);
     $answerMatching = array();
     while ($real_answer = Database::fetch_array($res_answer)) {
         $answerMatching[$real_answer['id_auto']] = $real_answer['answer'];
     }
     $real_answers = array();
     $quiz_question_options = Question::readQuestionOption($questionId, $course_id);
     $organs_at_risk_hit = 0;
     $questionScore = 0;
     if ($debug) {
         error_log('Start answer loop ');
     }
     $answer_correct_array = array();
     for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
         $answer = $objAnswerTmp->selectAnswer($answerId);
         $answerComment = $objAnswerTmp->selectComment($answerId);
         $answerCorrect = $objAnswerTmp->isCorrect($answerId);
         $answerWeighting = (double) $objAnswerTmp->selectWeighting($answerId);
         $answerAutoId = $objAnswerTmp->selectAutoId($answerId);
         $answer_correct_array[$answerId] = (bool) $answerCorrect;
         if ($debug) {
             error_log("answer auto id: {$answerAutoId} ");
             error_log("answer correct: {$answerCorrect} ");
         }
         // Delineation
         $delineation_cord = $objAnswerTmp->selectHotspotCoordinates(1);
         $answer_delineation_destination = $objAnswerTmp->selectDestination(1);
         switch ($answerType) {
             // for unique answer
             case UNIQUE_ANSWER:
             case UNIQUE_ANSWER_IMAGE:
             case UNIQUE_ANSWER_NO_OPTION:
                 if ($from_database) {
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE\n                                    exe_id = '" . $exeId . "' AND\n                                    question_id= '" . $questionId . "'";
                     $result = Database::query($sql);
                     $choice = Database::result($result, 0, "answer");
                     $studentChoice = $choice == $answerAutoId ? 1 : 0;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                         $totalScore += $answerWeighting;
                     }
                 } else {
                     $studentChoice = $choice == $answerAutoId ? 1 : 0;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                         $totalScore += $answerWeighting;
                     }
                 }
                 break;
                 // for multiple answers
             // for multiple answers
             case MULTIPLE_ANSWER_TRUE_FALSE:
                 if ($from_database) {
                     $choice = array();
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE\n                                    exe_id = {$exeId} AND\n                                    question_id = " . $questionId;
                     $result = Database::query($sql);
                     while ($row = Database::fetch_array($result)) {
                         $ind = $row['answer'];
                         $values = explode(':', $ind);
                         $my_answer_id = isset($values[0]) ? $values[0] : '';
                         $option = isset($values[1]) ? $values[1] : '';
                         $choice[$my_answer_id] = $option;
                     }
                 }
                 $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                 if (!empty($studentChoice)) {
                     if ($studentChoice == $answerCorrect) {
                         $questionScore += $true_score;
                     } else {
                         if ($quiz_question_options[$studentChoice]['name'] == "Don't know" || $quiz_question_options[$studentChoice]['name'] == "DoubtScore") {
                             $questionScore += $doubt_score;
                         } else {
                             $questionScore += $false_score;
                         }
                     }
                 } else {
                     // If no result then the user just hit don't know
                     $studentChoice = 3;
                     $questionScore += $doubt_score;
                 }
                 $totalScore = $questionScore;
                 break;
             case MULTIPLE_ANSWER:
                 //2
                 if ($from_database) {
                     $choice = array();
                     $sql = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $choice[$ind] = 1;
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     $real_answers[$answerId] = (bool) $studentChoice;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                     }
                 } else {
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     $real_answers[$answerId] = (bool) $studentChoice;
                     if (isset($studentChoice)) {
                         $questionScore += $answerWeighting;
                     }
                 }
                 $totalScore += $answerWeighting;
                 if ($debug) {
                     error_log("studentChoice: {$studentChoice}");
                 }
                 break;
             case GLOBAL_MULTIPLE_ANSWER:
                 if ($from_database) {
                     $choice = array();
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $choice[$ind] = 1;
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     $real_answers[$answerId] = (bool) $studentChoice;
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                     }
                 } else {
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     if (isset($studentChoice)) {
                         $questionScore += $answerWeighting;
                     }
                     $real_answers[$answerId] = (bool) $studentChoice;
                 }
                 $totalScore += $answerWeighting;
                 if ($debug) {
                     error_log("studentChoice: {$studentChoice}");
                 }
                 break;
             case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
                 if ($from_database) {
                     $sql = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                WHERE exe_id = {$exeId} AND question_id= " . $questionId;
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $result = explode(':', $ind);
                         if (isset($result[0])) {
                             $my_answer_id = isset($result[0]) ? $result[0] : '';
                             $option = isset($result[1]) ? $result[1] : '';
                             $choice[$my_answer_id] = $option;
                         }
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : '';
                     if ($answerCorrect == $studentChoice) {
                         //$answerCorrect = 1;
                         $real_answers[$answerId] = true;
                     } else {
                         //$answerCorrect = 0;
                         $real_answers[$answerId] = false;
                     }
                 } else {
                     $studentChoice = $choice[$answerAutoId];
                     if ($answerCorrect == $studentChoice) {
                         //$answerCorrect = 1;
                         $real_answers[$answerId] = true;
                     } else {
                         //$answerCorrect = 0;
                         $real_answers[$answerId] = false;
                     }
                 }
                 break;
             case MULTIPLE_ANSWER_COMBINATION:
                 if ($from_database) {
                     $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                WHERE exe_id = {$exeId} AND question_id= {$questionId}";
                     $resultans = Database::query($sql);
                     while ($row = Database::fetch_array($resultans)) {
                         $ind = $row['answer'];
                         $choice[$ind] = 1;
                     }
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     if ($answerCorrect == 1) {
                         if ($studentChoice) {
                             $real_answers[$answerId] = true;
                         } else {
                             $real_answers[$answerId] = false;
                         }
                     } else {
                         if ($studentChoice) {
                             $real_answers[$answerId] = false;
                         } else {
                             $real_answers[$answerId] = true;
                         }
                     }
                 } else {
                     $studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : null;
                     if ($answerCorrect == 1) {
                         if ($studentChoice) {
                             $real_answers[$answerId] = true;
                         } else {
                             $real_answers[$answerId] = false;
                         }
                     } else {
                         if ($studentChoice) {
                             $real_answers[$answerId] = false;
                         } else {
                             $real_answers[$answerId] = true;
                         }
                     }
                 }
                 break;
             case FILL_IN_BLANKS:
                 $str = '';
                 if ($from_database) {
                     $sql = "SELECT answer\n                                    FROM {$TBL_TRACK_ATTEMPT}\n                                    WHERE\n                                        exe_id = {$exeId} AND\n                                        question_id= " . intval($questionId);
                     $result = Database::query($sql);
                     $str = Database::result($result, 0, 'answer');
                 }
                 if ($saved_results == false && strpos($str, 'font color') !== false) {
                     // the question is encoded like this
                     // [A] B [C] D [E] F::10,10,10@1
                     // number 1 before the "@" means that is a switchable fill in blank question
                     // [A] B [C] D [E] F::10,10,10@ or  [A] B [C] D [E] F::10,10,10
                     // means that is a normal fill blank question
                     // first we explode the "::"
                     $pre_array = explode('::', $answer);
                     // is switchable fill blank or not
                     $last = count($pre_array) - 1;
                     $is_set_switchable = explode('@', $pre_array[$last]);
                     $switchable_answer_set = false;
                     if (isset($is_set_switchable[1]) && $is_set_switchable[1] == 1) {
                         $switchable_answer_set = true;
                     }
                     $answer = '';
                     for ($k = 0; $k < $last; $k++) {
                         $answer .= $pre_array[$k];
                     }
                     // splits weightings that are joined with a comma
                     $answerWeighting = explode(',', $is_set_switchable[0]);
                     // we save the answer because it will be modified
                     $temp = $answer;
                     $answer = '';
                     $j = 0;
                     //initialise answer tags
                     $user_tags = $correct_tags = $real_text = array();
                     // the loop will stop at the end of the text
                     while (1) {
                         // quits the loop if there are no more blanks (detect '[')
                         if (($pos = api_strpos($temp, '[')) === false) {
                             // adds the end of the text
                             $answer = $temp;
                             $real_text[] = $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
                         $real_text[] = 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) {
                             $queryfill = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                          WHERE\n                                            exe_id = '" . $exeId . "' AND\n                                            question_id= " . intval($questionId) . "";
                             $resfill = Database::query($queryfill);
                             $str = Database::result($resfill, 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], ' / ');
                                 $choice[$j] = api_substr($choice[$j], 0, $tmp);
                                 $choice[$j] = trim($choice[$j]);
                                 // Needed to let characters ' and " to work as part of an answer
                                 $choice[$j] = stripslashes($choice[$j]);
                             } else {
                                 $choice[$j] = null;
                             }
                         } else {
                             // 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[]
                         $correct_tags[] = api_substr($temp, 0, $pos);
                         $j++;
                         $temp = api_substr($temp, $pos + 1);
                     }
                     $answer = '';
                     $real_correct_tags = $correct_tags;
                     $chosen_list = array();
                     for ($i = 0; $i < count($real_correct_tags); $i++) {
                         if ($i == 0) {
                             $answer .= $real_text[0];
                         }
                         if (!$switchable_answer_set) {
                             // Needed to parse ' and " characters
                             $user_tags[$i] = stripslashes($user_tags[$i]);
                             if ($correct_tags[$i] == $user_tags[$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 .= $correct_tags[$i];
                             } elseif (!empty($user_tags[$i])) {
                                 // else if the word entered by the student IS NOT the same as the one defined by the professor
                                 // adds the word in red at the end of the string, and strikes it
                                 $answer .= '<font color="red"><s>' . $user_tags[$i] . '</s></font>';
                             } else {
                                 // adds a tabulation if no word has been typed by the student
                                 $answer .= '';
                                 // remove &nbsp; that causes issue
                             }
                         } else {
                             // switchable fill in the blanks
                             if (in_array($user_tags[$i], $correct_tags)) {
                                 $chosen_list[] = $user_tags[$i];
                                 $correct_tags = array_diff($correct_tags, $chosen_list);
                                 // 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 .= $user_tags[$i];
                             } elseif (!empty($user_tags[$i])) {
                                 // else if the word entered by the student IS NOT the same as the one defined by the professor
                                 // adds the word in red at the end of the string, and strikes it
                                 $answer .= '<font color="red"><s>' . $user_tags[$i] . '</s></font>';
                             } else {
                                 // adds a tabulation if no word has been typed by the student
                                 $answer .= '';
                                 // remove &nbsp; that causes issue
                             }
                         }
                         // adds the correct word, followed by ] to close the blank
                         $answer .= ' / <font color="green"><b>' . $real_correct_tags[$i] . '</b></font>]';
                         if (isset($real_text[$i + 1])) {
                             $answer .= $real_text[$i + 1];
                         }
                     }
                 } else {
                     // insert the student result in the track_e_attempt table, field answer
                     // $answer is the answer like in the c_quiz_answer table for the question
                     // student data are choice[]
                     $listCorrectAnswers = FillBlanks::getAnswerInfo($answer);
                     $switchableAnswerSet = $listCorrectAnswers["switchable"];
                     $answerWeighting = $listCorrectAnswers["tabweighting"];
                     // user choices is an array $choice
                     // get existing user data in n the BDD
                     if ($from_database) {
                         $sql = "SELECT answer\n                                    FROM {$TBL_TRACK_ATTEMPT}\n                                    WHERE\n                                        exe_id = {$exeId} AND\n                                        question_id= " . intval($questionId);
                         $result = Database::query($sql);
                         $str = Database::result($result, 0, 'answer');
                         $listStudentResults = FillBlanks::getAnswerInfo($str, true);
                         $choice = $listStudentResults['studentanswer'];
                     }
                     // loop other all blanks words
                     if (!$switchableAnswerSet) {
                         // not switchable answer, must be in the same place than teacher order
                         for ($i = 0; $i < count($listCorrectAnswers['tabwords']); $i++) {
                             $studentAnswer = isset($choice[$i]) ? trim($choice[$i]) : '';
                             // This value is the user input, not escaped while correct answer is escaped by fckeditor
                             // Works with cyrillic alphabet and when using ">" chars see #7718 #7610 #7618
                             if (!$from_database) {
                                 $studentAnswer = htmlentities(api_utf8_encode($studentAnswer));
                             }
                             $correctAnswer = $listCorrectAnswers['tabwords'][$i];
                             $isAnswerCorrect = 0;
                             if (FillBlanks::isGoodStudentAnswer($studentAnswer, $correctAnswer)) {
                                 // gives the related weighting to the student
                                 $questionScore += $answerWeighting[$i];
                                 // increments total score
                                 $totalScore += $answerWeighting[$i];
                                 $isAnswerCorrect = 1;
                             }
                             $listCorrectAnswers['studentanswer'][$i] = $studentAnswer;
                             $listCorrectAnswers['studentscore'][$i] = $isAnswerCorrect;
                         }
                     } else {
                         // switchable answer
                         $listStudentAnswerTemp = $choice;
                         $listTeacherAnswerTemp = $listCorrectAnswers['tabwords'];
                         // for every teacher answer, check if there is a student answer
                         for ($i = 0; $i < count($listStudentAnswerTemp); $i++) {
                             $studentAnswer = trim($listStudentAnswerTemp[$i]);
                             $found = false;
                             for ($j = 0; $j < count($listTeacherAnswerTemp); $j++) {
                                 $correctAnswer = $listTeacherAnswerTemp[$j];
                                 if (!$found) {
                                     if (FillBlanks::isGoodStudentAnswer($studentAnswer, $correctAnswer)) {
                                         $questionScore += $answerWeighting[$i];
                                         $totalScore += $answerWeighting[$i];
                                         $listTeacherAnswerTemp[$j] = "";
                                         $found = true;
                                     }
                                 }
                             }
                             $listCorrectAnswers['studentanswer'][$i] = $studentAnswer;
                             if (!$found) {
                                 $listCorrectAnswers['studentscore'][$i] = 0;
                             } else {
                                 $listCorrectAnswers['studentscore'][$i] = 1;
                             }
                         }
                     }
                     $answer = FillBlanks::getAnswerInStudentAttempt($listCorrectAnswers);
                 }
                 break;
                 // for calculated answer
             // for calculated answer
             case CALCULATED_ANSWER:
                 $calculatedAnswer = Session::read('calculatedAnswerId');
                 $answer = $objAnswerTmp->selectAnswer($calculatedAnswer[$questionId]);
                 $preArray = explode('@@', $answer);
                 $last = count($preArray) - 1;
                 $answer = '';
                 for ($k = 0; $k < $last; $k++) {
                     $answer .= $preArray[$k];
                 }
                 $answerWeighting = array($answerWeighting);
                 // we save the answer because it will be modified
                 $temp = $answer;
                 $answer = '';
                 $j = 0;
                 //initialise answer tags
                 $userTags = $correctTags = $realText = array();
                 // the loop will stop at the end of the text
                 while (1) {
                     // quits the loop if there are no more blanks (detect '[')
                     if (($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) {
                         $queryfill = "SELECT answer FROM " . $TBL_TRACK_ATTEMPT . "\n                                          WHERE\n                                            exe_id = '" . $exeId . "' AND\n                                            question_id= " . intval($questionId) . "";
                         $resfill = Database::query($queryfill);
                         $str = Database::result($resfill, 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], ' / ');
                             $choice[$j] = api_substr($choice[$j], 0, $tmp);
                             $choice[$j] = trim($choice[$j]);
                             // Needed to let characters ' and " to work as part of an answer
                             $choice[$j] = stripslashes($choice[$j]);
                         } else {
                             $choice[$j] = null;
                         }
                     } 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;
                 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];
                     } elseif (!empty($userTags[$i])) {
                         // else if the word entered by the student IS NOT the same as the one defined by the professor
                         // adds the word in red at the end of the string, and strikes it
                         $answer .= '<font color="red"><s>' . $userTags[$i] . '</s></font>';
                     } else {
                         // adds a tabulation if no word has been typed by the student
                         $answer .= '';
                         // remove &nbsp; that causes issue
                     }
                     // adds the correct word, followed by ] to close the blank
                     $answer .= ' / <font color="green"><b>' . $realCorrectTags[$i] . '</b></font>]';
                     if (isset($realText[$i + 1])) {
                         $answer .= $realText[$i + 1];
                     }
                 }
                 break;
                 // for free answer
             // for free answer
             case FREE_ANSWER:
                 if ($from_database) {
                     $query = "SELECT answer, marks FROM " . $TBL_TRACK_ATTEMPT . "\n                                   WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resq = Database::query($query);
                     $data = Database::fetch_array($resq);
                     $choice = $data['answer'];
                     $choice = str_replace('\\r\\n', '', $choice);
                     $choice = stripslashes($choice);
                     $questionScore = $data['marks'];
                     if ($questionScore == -1) {
                         $totalScore += 0;
                     } else {
                         $totalScore += $questionScore;
                     }
                     if ($questionScore == '') {
                         $questionScore = 0;
                     }
                     $arrques = $questionName;
                     $arrans = $choice;
                 } else {
                     $studentChoice = $choice;
                     if ($studentChoice) {
                         //Fixing negative puntation see #2193
                         $questionScore = 0;
                         $totalScore += 0;
                     }
                 }
                 break;
             case ORAL_EXPRESSION:
                 if ($from_database) {
                     $query = "SELECT answer, marks FROM " . $TBL_TRACK_ATTEMPT . "\n                                   WHERE exe_id = '" . $exeId . "' AND question_id= '" . $questionId . "'";
                     $resq = Database::query($query);
                     $choice = Database::result($resq, 0, 'answer');
                     $choice = str_replace('\\r\\n', '', $choice);
                     $choice = stripslashes($choice);
                     $questionScore = Database::result($resq, 0, "marks");
                     if ($questionScore == -1) {
                         $totalScore += 0;
                     } else {
                         $totalScore += $questionScore;
                     }
                     $arrques = $questionName;
                     $arrans = $choice;
                 } else {
                     $studentChoice = $choice;
                     if ($studentChoice) {
                         //Fixing negative puntation see #2193
                         $questionScore = 0;
                         $totalScore += 0;
                     }
                 }
                 break;
             case DRAGGABLE:
                 //no break
             //no break
             case MATCHING_DRAGGABLE:
                 //no break
             //no break
             case MATCHING:
                 if ($from_database) {
                     $sql = 'SELECT id, answer, id_auto
                             FROM ' . $table_ans . '
                             WHERE
                                 c_id = ' . $course_id . ' AND
                                 question_id = "' . $questionId . '" AND
                                 correct = 0';
                     $res_answer = Database::query($sql);
                     // Getting the real answer
                     $real_list = array();
                     while ($real_answer = Database::fetch_array($res_answer)) {
                         $real_list[$real_answer['id_auto']] = $real_answer['answer'];
                     }
                     $sql = 'SELECT id, answer, correct, id_auto, ponderation
                             FROM ' . $table_ans . '
                             WHERE
                                 c_id = ' . $course_id . ' AND
                                 question_id="' . $questionId . '" AND
                                 correct <> 0
                             ORDER BY id_auto';
                     $res_answers = Database::query($sql);
                     $questionScore = 0;
                     while ($a_answers = Database::fetch_array($res_answers)) {
                         $i_answer_id = $a_answers['id'];
                         //3
                         $s_answer_label = $a_answers['answer'];
                         // your daddy - your mother
                         $i_answer_correct_answer = $a_answers['correct'];
                         //1 - 2
                         $i_answer_id_auto = $a_answers['id_auto'];
                         // 3 - 4
                         $sql = "SELECT answer FROM {$TBL_TRACK_ATTEMPT}\n                                    WHERE\n                                        exe_id = '{$exeId}' AND\n                                        question_id = '{$questionId}' AND\n                                        position = '{$i_answer_id_auto}'";
                         $res_user_answer = Database::query($sql);
                         if (Database::num_rows($res_user_answer) > 0) {
                             //  rich - good looking
                             $s_user_answer = Database::result($res_user_answer, 0, 0);
                         } else {
                             $s_user_answer = 0;
                         }
                         $i_answerWeighting = $a_answers['ponderation'];
                         $user_answer = '';
                         if (!empty($s_user_answer)) {
                             if ($answerType == DRAGGABLE) {
                                 if ($s_user_answer == $i_answer_correct_answer) {
                                     $questionScore += $i_answerWeighting;
                                     $totalScore += $i_answerWeighting;
                                     $user_answer = Display::label(get_lang('Correct'), 'success');
                                 } else {
                                     $user_answer = Display::label(get_lang('Incorrect'), 'danger');
                                 }
                             } else {
                                 if ($s_user_answer == $i_answer_correct_answer) {
                                     $questionScore += $i_answerWeighting;
                                     $totalScore += $i_answerWeighting;
                                     if (isset($real_list[$i_answer_id])) {
                                         $user_answer = Display::span($real_list[$i_answer_id]);
                                     }
                                 } else {
                                     $user_answer = Display::span($real_list[$s_user_answer], ['style' => 'color: #FF0000; text-decoration: line-through;']);
                                 }
                             }
                         } elseif ($answerType == DRAGGABLE) {
                             $user_answer = Display::label(get_lang('Incorrect'), 'danger');
                         }
                         if ($show_result) {
                             echo '<tr>';
                             echo '<td>' . $s_answer_label . '</td>';
                             echo '<td>' . $user_answer;
                             if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                                 if (isset($real_list[$i_answer_correct_answer])) {
                                     echo Display::span($real_list[$i_answer_correct_answer], ['style' => 'color: #008000; font-weight: bold;']);
                                 }
                             }
                             echo '</td>';
                             echo '</tr>';
                         }
                     }
                     break 2;
                     // break the switch and the "for" condition
                 } else {
                     if ($answerCorrect) {
                         if (isset($choice[$answerAutoId]) && $answerCorrect == $choice[$answerAutoId]) {
                             $questionScore += $answerWeighting;
                             $totalScore += $answerWeighting;
                             $user_answer = Display::span($answerMatching[$choice[$answerAutoId]]);
                         } else {
                             if (isset($answerMatching[$choice[$answerAutoId]])) {
                                 $user_answer = Display::span($answerMatching[$choice[$answerAutoId]], ['style' => 'color: #FF0000; text-decoration: line-through;']);
                             }
                         }
                         $matching[$answerAutoId] = $choice[$answerAutoId];
                     }
                     break;
                 }
             case HOT_SPOT:
                 if ($from_database) {
                     $TBL_TRACK_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
                     $sql = "SELECT hotspot_correct\n                                FROM {$TBL_TRACK_HOTSPOT}\n                                WHERE\n                                    hotspot_exe_id = '" . $exeId . "' AND\n                                    hotspot_question_id= '" . $questionId . "' AND\n                                    hotspot_answer_id = " . intval($answerAutoId) . "";
                     $result = Database::query($sql);
                     $studentChoice = Database::result($result, 0, "hotspot_correct");
                     if ($studentChoice) {
                         $questionScore += $answerWeighting;
                         $totalScore += $answerWeighting;
                     }
                 } else {
                     if (!isset($choice[$answerAutoId])) {
                         $choice[$answerAutoId] = 0;
                     } else {
                         $studentChoice = $choice[$answerAutoId];
                         $choiceIsValid = false;
                         if (!empty($studentChoice)) {
                             $hotspotType = $objAnswerTmp->selectHotspotType($answerId);
                             $hotspotCoordinates = $objAnswerTmp->selectHotspotCoordinates($answerId);
                             $choicePoint = Geometry::decodePoint($studentChoice);
                             switch ($hotspotType) {
                                 case 'square':
                                     $hotspotProperties = Geometry::decodeSquare($hotspotCoordinates);
                                     $choiceIsValid = Geometry::pointIsInSquare($hotspotProperties, $choicePoint);
                                     break;
                                 case 'circle':
                                     $hotspotProperties = Geometry::decodeEllipse($hotspotCoordinates);
                                     $choiceIsValid = Geometry::pointIsInEllipse($hotspotProperties, $choicePoint);
                                     break;
                                 case 'poly':
                                     $hotspotProperties = Geometry::decodePolygon($hotspotCoordinates);
                                     $choiceIsValid = Geometry::pointIsInPolygon($hotspotProperties, $choicePoint);
                                     break;
                             }
                         }
                         $choice[$answerAutoId] = 0;
                         if ($choiceIsValid) {
                             $questionScore += $answerWeighting;
                             $totalScore += $answerWeighting;
                             $choice[$answerAutoId] = 1;
                         }
                     }
                 }
                 break;
                 // @todo never added to chamilo
                 //for hotspot with fixed order
             // @todo never added to chamilo
             //for hotspot with fixed order
             case HOT_SPOT_ORDER:
                 $studentChoice = $choice['order'][$answerId];
                 if ($studentChoice == $answerId) {
                     $questionScore += $answerWeighting;
                     $totalScore += $answerWeighting;
                     $studentChoice = true;
                 } else {
                     $studentChoice = false;
                 }
                 break;
                 // for hotspot with delineation
             // for hotspot with delineation
             case HOT_SPOT_DELINEATION:
                 if ($from_database) {
                     // getting the user answer
                     $TBL_TRACK_HOTSPOT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
                     $query = "SELECT hotspot_correct, hotspot_coordinate\n                                    FROM {$TBL_TRACK_HOTSPOT}\n                                    WHERE\n                                        hotspot_exe_id = '" . $exeId . "' AND\n                                        hotspot_question_id= '" . $questionId . "' AND\n                                        hotspot_answer_id='1'";
                     //by default we take 1 because it's a delineation
                     $resq = Database::query($query);
                     $row = Database::fetch_array($resq, 'ASSOC');
                     $choice = $row['hotspot_correct'];
                     $user_answer = $row['hotspot_coordinate'];
                     // THIS is very important otherwise the poly_compile will throw an error!!
                     // round-up the coordinates
                     $coords = explode('/', $user_answer);
                     $user_array = '';
                     foreach ($coords as $coord) {
                         list($x, $y) = explode(';', $coord);
                         $user_array .= round($x) . ';' . round($y) . '/';
                     }
                     $user_array = substr($user_array, 0, -1);
                 } else {
                     if (!empty($studentChoice)) {
                         $newquestionList[] = $questionId;
                     }
                     if ($answerId === 1) {
                         $studentChoice = $choice[$answerId];
                         $questionScore += $answerWeighting;
                         if ($hotspot_delineation_result[1] == 1) {
                             $totalScore += $answerWeighting;
                             //adding the total
                         }
                     }
                 }
                 $_SESSION['hotspot_coord'][1] = $delineation_cord;
                 $_SESSION['hotspot_dest'][1] = $answer_delineation_destination;
                 break;
         }
         // end switch Answertype
         if ($show_result) {
             if ($debug) {
                 error_log('show result ' . $show_result);
             }
             if ($from == 'exercise_result') {
                 if ($debug) {
                     error_log('Showing questions $from ' . $from);
                 }
                 //display answers (if not matching type, or if the answer is correct)
                 if (!in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE]) || $answerCorrect) {
                     if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, GLOBAL_MULTIPLE_ANSWER))) {
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, 0, 0, $results_disabled);
                         //}
                     } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                         //if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, $questionId, 0, $results_disabled);
                         //}
                     } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                         //	if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, 0, 0, 0, $results_disabled);
                         //}
                     } elseif ($answerType == FILL_IN_BLANKS) {
                         //if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer, 0, 0, $results_disabled);
                         //	}
                     } elseif ($answerType == CALCULATED_ANSWER) {
                         //if ($origin!='learnpath') {
                         ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer, 0, 0);
                         //  }
                     } elseif ($answerType == FREE_ANSWER) {
                         //if($origin != 'learnpath') {
                         ExerciseShowFunctions::display_free_answer($feedback_type, $choice, $exeId, $questionId, $questionScore);
                         //}
                     } elseif ($answerType == ORAL_EXPRESSION) {
                         // to store the details of open questions in an array to be used in mail
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_oral_expression_answer($feedback_type, $choice, 0, 0, $nano);
                         //}
                     } elseif ($answerType == HOT_SPOT) {
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_hotspot_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment, $results_disabled);
                         //	}
                     } elseif ($answerType == HOT_SPOT_ORDER) {
                         //if ($origin != 'learnpath') {
                         ExerciseShowFunctions::display_hotspot_order_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment);
                         //}
                     } elseif ($answerType == HOT_SPOT_DELINEATION) {
                         $user_answer = $_SESSION['exerciseResultCoordinates'][$questionId];
                         //round-up the coordinates
                         $coords = explode('/', $user_answer);
                         $user_array = '';
                         foreach ($coords as $coord) {
                             list($x, $y) = explode(';', $coord);
                             $user_array .= round($x) . ';' . round($y) . '/';
                         }
                         $user_array = substr($user_array, 0, -1);
                         if ($next) {
                             $user_answer = $user_array;
                             // we compare only the delineation not the other points
                             $answer_question = $_SESSION['hotspot_coord'][1];
                             $answerDestination = $_SESSION['hotspot_dest'][1];
                             //calculating the area
                             $poly_user = convert_coordinates($user_answer, '/');
                             $poly_answer = convert_coordinates($answer_question, '|');
                             $max_coord = poly_get_max($poly_user, $poly_answer);
                             $poly_user_compiled = poly_compile($poly_user, $max_coord);
                             $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                             $poly_results = poly_result($poly_answer_compiled, $poly_user_compiled, $max_coord);
                             $overlap = $poly_results['both'];
                             $poly_answer_area = $poly_results['s1'];
                             $poly_user_area = $poly_results['s2'];
                             $missing = $poly_results['s1Only'];
                             $excess = $poly_results['s2Only'];
                             //$overlap = round(polygons_overlap($poly_answer,$poly_user));
                             // //this is an area in pixels
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' - Polygons results are ' . print_r($poly_results, 1), 0);
                             }
                             if ($overlap < 1) {
                                 //shortcut to avoid complicated calculations
                                 $final_overlap = 0;
                                 $final_missing = 100;
                                 $final_excess = 100;
                             } else {
                                 // the final overlap is the percentage of the initial polygon
                                 // that is overlapped by the user's polygon
                                 $final_overlap = round((double) $overlap / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final overlap is ' . $final_overlap, 0);
                                 }
                                 // the final missing area is the percentage of the initial polygon
                                 // that is not overlapped by the user's polygon
                                 $final_missing = 100 - $final_overlap;
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final missing is ' . $final_missing, 0);
                                 }
                                 // the final excess area is the percentage of the initial polygon's size
                                 // that is covered by the user's polygon outside of the initial polygon
                                 $final_excess = round(((double) $poly_user_area - (double) $overlap) / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final excess is ' . $final_excess, 0);
                                 }
                             }
                             //checking the destination parameters parsing the "@@"
                             $destination_items = explode('@@', $answerDestination);
                             $threadhold_total = $destination_items[0];
                             $threadhold_items = explode(';', $threadhold_total);
                             $threadhold1 = $threadhold_items[0];
                             // overlap
                             $threadhold2 = $threadhold_items[1];
                             // excess
                             $threadhold3 = $threadhold_items[2];
                             //missing
                             // if is delineation
                             if ($answerId === 1) {
                                 //setting colors
                                 if ($final_overlap >= $threadhold1) {
                                     $overlap_color = true;
                                     //echo 'a';
                                 }
                                 //echo $excess.'-'.$threadhold2;
                                 if ($final_excess <= $threadhold2) {
                                     $excess_color = true;
                                     //echo 'b';
                                 }
                                 //echo '--------'.$missing.'-'.$threadhold3;
                                 if ($final_missing <= $threadhold3) {
                                     $missing_color = true;
                                     //echo 'c';
                                 }
                                 // if pass
                                 if ($final_overlap >= $threadhold1 && $final_missing <= $threadhold3 && $final_excess <= $threadhold2) {
                                     $next = 1;
                                     //go to the oars
                                     $result_comment = get_lang('Acceptable');
                                     $final_answer = 1;
                                     // do not update with  update_exercise_attempt
                                 } else {
                                     $next = 0;
                                     $result_comment = get_lang('Unacceptable');
                                     $comment = $answerDestination = $objAnswerTmp->selectComment(1);
                                     $answerDestination = $objAnswerTmp->selectDestination(1);
                                     //checking the destination parameters parsing the "@@"
                                     $destination_items = explode('@@', $answerDestination);
                                 }
                             } elseif ($answerId > 1) {
                                 if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - answerId is of type noerror', 0);
                                     }
                                     //type no error shouldn't be treated
                                     $next = 1;
                                     continue;
                                 }
                                 if ($debug > 0) {
                                     error_log(__LINE__ . ' - answerId is >1 so we\'re probably in OAR', 0);
                                 }
                                 //check the intersection between the oar and the user
                                 //echo 'user';	print_r($x_user_list);		print_r($y_user_list);
                                 //echo 'official';print_r($x_list);print_r($y_list);
                                 //$result = get_intersection_data($x_list,$y_list,$x_user_list,$y_user_list);
                                 $inter = $result['success'];
                                 //$delineation_cord=$objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $poly_answer = convert_coordinates($delineation_cord, '|');
                                 $max_coord = poly_get_max($poly_user, $poly_answer);
                                 $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                                 $overlap = poly_touch($poly_user_compiled, $poly_answer_compiled, $max_coord);
                                 if ($overlap == false) {
                                     //all good, no overlap
                                     $next = 1;
                                     continue;
                                 } else {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - Overlap is ' . $overlap . ': OAR hit', 0);
                                     }
                                     $organs_at_risk_hit++;
                                     //show the feedback
                                     $next = 0;
                                     $comment = $answerDestination = $objAnswerTmp->selectComment($answerId);
                                     $answerDestination = $objAnswerTmp->selectDestination($answerId);
                                     $destination_items = explode('@@', $answerDestination);
                                     $try_hotspot = $destination_items[1];
                                     $lp_hotspot = $destination_items[2];
                                     $select_question_hotspot = $destination_items[3];
                                     $url_hotspot = $destination_items[4];
                                 }
                             }
                         } else {
                             // the first delineation feedback
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' first', 0);
                             }
                         }
                     } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                         echo '<tr>';
                         echo Display::tag('td', $answerMatching[$answerId]);
                         echo Display::tag('td', "{$user_answer} / " . Display::tag('strong', $answerMatching[$answerCorrect], ['style' => 'color: #008000; font-weight: bold;']));
                         echo '</tr>';
                     }
                 }
             } else {
                 if ($debug) {
                     error_log('Showing questions $from ' . $from);
                 }
                 switch ($answerType) {
                     case UNIQUE_ANSWER:
                     case UNIQUE_ANSWER_IMAGE:
                     case UNIQUE_ANSWER_NO_OPTION:
                     case MULTIPLE_ANSWER:
                     case GLOBAL_MULTIPLE_ANSWER:
                     case MULTIPLE_ANSWER_COMBINATION:
                         if ($answerId == 1) {
                             ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, $answerId, $results_disabled);
                         } else {
                             ExerciseShowFunctions::display_unique_or_multiple_answer($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, "", $results_disabled);
                         }
                         break;
                     case MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE:
                         if ($answerId == 1) {
                             ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, $answerId, $results_disabled);
                         } else {
                             ExerciseShowFunctions::display_multiple_answer_combination_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, "", $results_disabled);
                         }
                         break;
                     case MULTIPLE_ANSWER_TRUE_FALSE:
                         if ($answerId == 1) {
                             ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, $answerId, $results_disabled);
                         } else {
                             ExerciseShowFunctions::display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $exeId, $questionId, "", $results_disabled);
                         }
                         break;
                     case FILL_IN_BLANKS:
                         ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer, $exeId, $questionId, $results_disabled, $str);
                         break;
                     case CALCULATED_ANSWER:
                         ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer, $exeId, $questionId);
                         break;
                     case FREE_ANSWER:
                         echo ExerciseShowFunctions::display_free_answer($feedback_type, $choice, $exeId, $questionId, $questionScore);
                         break;
                     case ORAL_EXPRESSION:
                         echo '<tr>
                             <td valign="top">' . ExerciseShowFunctions::display_oral_expression_answer($feedback_type, $choice, $exeId, $questionId, $nano) . '</td>
                             </tr>
                             </table>';
                         break;
                     case HOT_SPOT:
                         ExerciseShowFunctions::display_hotspot_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment, $results_disabled);
                         break;
                     case HOT_SPOT_DELINEATION:
                         $user_answer = $user_array;
                         if ($next) {
                             //$tbl_track_e_hotspot = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
                             // Save into db
                             /*	$sql = "INSERT INTO $tbl_track_e_hotspot (
                                 * hotspot_user_id,
                                 *  hotspot_course_code,
                                 *  hotspot_exe_id,
                                 *  hotspot_question_id,
                                 *  hotspot_answer_id,
                                 *  hotspot_correct,
                                 *  hotspot_coordinate
                                 *  )
                                VALUES (
                                 * '".Database::escape_string($_user['user_id'])."',
                                 *  '".Database::escape_string($_course['id'])."',
                                 *  '".Database::escape_string($exeId)."', '".Database::escape_string($questionId)."',
                                 *  '".Database::escape_string($answerId)."',
                                 *  '".Database::escape_string($studentChoice)."',
                                 *  '".Database::escape_string($user_array)."')";
                                $result = Database::query($sql,__FILE__,__LINE__);
                                 */
                             $user_answer = $user_array;
                             // we compare only the delineation not the other points
                             $answer_question = $_SESSION['hotspot_coord'][1];
                             $answerDestination = $_SESSION['hotspot_dest'][1];
                             //calculating the area
                             $poly_user = convert_coordinates($user_answer, '/');
                             $poly_answer = convert_coordinates($answer_question, '|');
                             $max_coord = poly_get_max($poly_user, $poly_answer);
                             $poly_user_compiled = poly_compile($poly_user, $max_coord);
                             $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                             $poly_results = poly_result($poly_answer_compiled, $poly_user_compiled, $max_coord);
                             $overlap = $poly_results['both'];
                             $poly_answer_area = $poly_results['s1'];
                             $poly_user_area = $poly_results['s2'];
                             $missing = $poly_results['s1Only'];
                             $excess = $poly_results['s2Only'];
                             //$overlap = round(polygons_overlap($poly_answer,$poly_user)); //this is an area in pixels
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' - Polygons results are ' . print_r($poly_results, 1), 0);
                             }
                             if ($overlap < 1) {
                                 //shortcut to avoid complicated calculations
                                 $final_overlap = 0;
                                 $final_missing = 100;
                                 $final_excess = 100;
                             } else {
                                 // the final overlap is the percentage of the initial polygon that is overlapped by the user's polygon
                                 $final_overlap = round((double) $overlap / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final overlap is ' . $final_overlap, 0);
                                 }
                                 // the final missing area is the percentage of the initial polygon that is not overlapped by the user's polygon
                                 $final_missing = 100 - $final_overlap;
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final missing is ' . $final_missing, 0);
                                 }
                                 // the final excess area is the percentage of the initial polygon's size that is covered by the user's polygon outside of the initial polygon
                                 $final_excess = round(((double) $poly_user_area - (double) $overlap) / (double) $poly_answer_area * 100);
                                 if ($debug > 1) {
                                     error_log(__LINE__ . ' - Final excess is ' . $final_excess, 0);
                                 }
                             }
                             //checking the destination parameters parsing the "@@"
                             $destination_items = explode('@@', $answerDestination);
                             $threadhold_total = $destination_items[0];
                             $threadhold_items = explode(';', $threadhold_total);
                             $threadhold1 = $threadhold_items[0];
                             // overlap
                             $threadhold2 = $threadhold_items[1];
                             // excess
                             $threadhold3 = $threadhold_items[2];
                             //missing
                             // if is delineation
                             if ($answerId === 1) {
                                 //setting colors
                                 if ($final_overlap >= $threadhold1) {
                                     $overlap_color = true;
                                     //echo 'a';
                                 }
                                 //echo $excess.'-'.$threadhold2;
                                 if ($final_excess <= $threadhold2) {
                                     $excess_color = true;
                                     //echo 'b';
                                 }
                                 //echo '--------'.$missing.'-'.$threadhold3;
                                 if ($final_missing <= $threadhold3) {
                                     $missing_color = true;
                                     //echo 'c';
                                 }
                                 // if pass
                                 if ($final_overlap >= $threadhold1 && $final_missing <= $threadhold3 && $final_excess <= $threadhold2) {
                                     $next = 1;
                                     //go to the oars
                                     $result_comment = get_lang('Acceptable');
                                     $final_answer = 1;
                                     // do not update with  update_exercise_attempt
                                 } else {
                                     $next = 0;
                                     $result_comment = get_lang('Unacceptable');
                                     $comment = $answerDestination = $objAnswerTmp->selectComment(1);
                                     $answerDestination = $objAnswerTmp->selectDestination(1);
                                     //checking the destination parameters parsing the "@@"
                                     $destination_items = explode('@@', $answerDestination);
                                 }
                             } elseif ($answerId > 1) {
                                 if ($objAnswerTmp->selectHotspotType($answerId) == 'noerror') {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - answerId is of type noerror', 0);
                                     }
                                     //type no error shouldn't be treated
                                     $next = 1;
                                     continue;
                                 }
                                 if ($debug > 0) {
                                     error_log(__LINE__ . ' - answerId is >1 so we\'re probably in OAR', 0);
                                 }
                                 //check the intersection between the oar and the user
                                 //echo 'user';	print_r($x_user_list);		print_r($y_user_list);
                                 //echo 'official';print_r($x_list);print_r($y_list);
                                 //$result = get_intersection_data($x_list,$y_list,$x_user_list,$y_user_list);
                                 $inter = $result['success'];
                                 //$delineation_cord=$objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $delineation_cord = $objAnswerTmp->selectHotspotCoordinates($answerId);
                                 $poly_answer = convert_coordinates($delineation_cord, '|');
                                 $max_coord = poly_get_max($poly_user, $poly_answer);
                                 $poly_answer_compiled = poly_compile($poly_answer, $max_coord);
                                 $overlap = poly_touch($poly_user_compiled, $poly_answer_compiled, $max_coord);
                                 if ($overlap == false) {
                                     //all good, no overlap
                                     $next = 1;
                                     continue;
                                 } else {
                                     if ($debug > 0) {
                                         error_log(__LINE__ . ' - Overlap is ' . $overlap . ': OAR hit', 0);
                                     }
                                     $organs_at_risk_hit++;
                                     //show the feedback
                                     $next = 0;
                                     $comment = $answerDestination = $objAnswerTmp->selectComment($answerId);
                                     $answerDestination = $objAnswerTmp->selectDestination($answerId);
                                     $destination_items = explode('@@', $answerDestination);
                                     $try_hotspot = $destination_items[1];
                                     $lp_hotspot = $destination_items[2];
                                     $select_question_hotspot = $destination_items[3];
                                     $url_hotspot = $destination_items[4];
                                 }
                             }
                         } else {
                             // the first delineation feedback
                             if ($debug > 0) {
                                 error_log(__LINE__ . ' first', 0);
                             }
                         }
                         break;
                     case HOT_SPOT_ORDER:
                         ExerciseShowFunctions::display_hotspot_order_answer($feedback_type, $answerId, $answer, $studentChoice, $answerComment);
                         break;
                     case DRAGGABLE:
                         //no break
                     //no break
                     case MATCHING_DRAGGABLE:
                         //no break
                     //no break
                     case MATCHING:
                         echo '<tr>';
                         echo Display::tag('td', $answerMatching[$answerId]);
                         echo Display::tag('td', "{$user_answer} / " . Display::tag('strong', $answerMatching[$answerCorrect], ['style' => 'color: #008000; font-weight: bold;']));
                         echo '</tr>';
                         break;
                 }
             }
         }
         if ($debug) {
             error_log(' ------ ');
         }
     }
     // end for that loops over all answers of the current question
     if ($debug) {
         error_log('-- end answer loop --');
     }
     $final_answer = true;
     foreach ($real_answers as $my_answer) {
         if (!$my_answer) {
             $final_answer = false;
         }
     }
     //we add the total score after dealing with the answers
     if ($answerType == MULTIPLE_ANSWER_COMBINATION || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
         if ($final_answer) {
             //getting only the first score where we save the weight of all the question
             $answerWeighting = $objAnswerTmp->selectWeighting(1);
             $questionScore += $answerWeighting;
             $totalScore += $answerWeighting;
         }
     }
     //Fixes multiple answer question in order to be exact
     //if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
     /* if ($answerType == GLOBAL_MULTIPLE_ANSWER) {
                 $diff = @array_diff($answer_correct_array, $real_answers);
     
                 // All good answers or nothing works like exact
     
                 $counter = 1;
                 $correct_answer = true;
                 foreach ($real_answers as $my_answer) {
                     if ($debug)
                         error_log(" my_answer: $my_answer answer_correct_array[counter]: ".$answer_correct_array[$counter]);
                     if ($my_answer != $answer_correct_array[$counter]) {
                         $correct_answer = false;
                         break;
                     }
                     $counter++;
                 }
     
                 if ($debug) error_log(" answer_correct_array: ".print_r($answer_correct_array, 1)."");
                 if ($debug) error_log(" real_answers: ".print_r($real_answers, 1)."");
                 if ($debug) error_log(" correct_answer: ".$correct_answer);
     
                 if ($correct_answer == false) {
                     $questionScore = 0;
                 }
     
                 // This makes the result non exact
                 if (!empty($diff)) {
                     $questionScore = 0;
                 }
             }*/
     $extra_data = array('final_overlap' => $final_overlap, 'final_missing' => $final_missing, 'final_excess' => $final_excess, 'overlap_color' => $overlap_color, 'missing_color' => $missing_color, 'excess_color' => $excess_color, 'threadhold1' => $threadhold1, 'threadhold2' => $threadhold2, 'threadhold3' => $threadhold3);
     if ($from == 'exercise_result') {
         // if answer is hotspot. To the difference of exercise_show.php,
         //  we use the results from the session (from_db=0)
         // TODO Change this, because it is wrong to show the user
         //  some results that haven't been stored in the database yet
         if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER || $answerType == HOT_SPOT_DELINEATION) {
             if ($debug) {
                 error_log('$from AND this is a hotspot kind of question ');
             }
             $my_exe_id = 0;
             $from_database = 0;
             if ($answerType == HOT_SPOT_DELINEATION) {
                 if (0) {
                     if ($overlap_color) {
                         $overlap_color = 'green';
                     } else {
                         $overlap_color = 'red';
                     }
                     if ($missing_color) {
                         $missing_color = 'green';
                     } else {
                         $missing_color = 'red';
                     }
                     if ($excess_color) {
                         $excess_color = 'green';
                     } else {
                         $excess_color = 'red';
                     }
                     if (!is_numeric($final_overlap)) {
                         $final_overlap = 0;
                     }
                     if (!is_numeric($final_missing)) {
                         $final_missing = 0;
                     }
                     if (!is_numeric($final_excess)) {
                         $final_excess = 0;
                     }
                     if ($final_overlap > 100) {
                         $final_overlap = 100;
                     }
                     $table_resume = '<table class="data_table">
                             <tr class="row_odd" >
                                 <td></td>
                                 <td ><b>' . get_lang('Requirements') . '</b></td>
                                 <td><b>' . get_lang('YourAnswer') . '</b></td>
                             </tr>
                             <tr class="row_even">
                                 <td><b>' . get_lang('Overlap') . '</b></td>
                                 <td>' . get_lang('Min') . ' ' . $threadhold1 . '</td>
                                 <td><div style="color:' . $overlap_color . '">' . ($final_overlap < 0 ? 0 : intval($final_overlap)) . '</div></td>
                             </tr>
                             <tr>
                                 <td><b>' . get_lang('Excess') . '</b></td>
                                 <td>' . get_lang('Max') . ' ' . $threadhold2 . '</td>
                                 <td><div style="color:' . $excess_color . '">' . ($final_excess < 0 ? 0 : intval($final_excess)) . '</div></td>
                             </tr>
                             <tr class="row_even">
                                 <td><b>' . get_lang('Missing') . '</b></td>
                                 <td>' . get_lang('Max') . ' ' . $threadhold3 . '</td>
                                 <td><div style="color:' . $missing_color . '">' . ($final_missing < 0 ? 0 : intval($final_missing)) . '</div></td>
                             </tr>
                         </table>';
                     if ($next == 0) {
                         $try = $try_hotspot;
                         $lp = $lp_hotspot;
                         $destinationid = $select_question_hotspot;
                         $url = $url_hotspot;
                     } else {
                         //show if no error
                         //echo 'no error';
                         $comment = $answerComment = $objAnswerTmp->selectComment($nbrAnswers);
                         $answerDestination = $objAnswerTmp->selectDestination($nbrAnswers);
                     }
                     echo '<h1><div style="color:#333;">' . get_lang('Feedback') . '</div></h1>
                         <p style="text-align:center">';
                     $message = '<p>' . get_lang('YourDelineation') . '</p>';
                     $message .= $table_resume;
                     $message .= '<br />' . get_lang('ResultIs') . ' ' . $result_comment . '<br />';
                     if ($organs_at_risk_hit > 0) {
                         $message .= '<p><b>' . get_lang('OARHit') . '</b></p>';
                     }
                     $message .= '<p>' . $comment . '</p>';
                     echo $message;
                 } else {
                     echo $hotspot_delineation_result[0];
                     //prints message
                     $from_database = 1;
                     // the hotspot_solution.swf needs this variable
                 }
                 //save the score attempts
                 if (1) {
                     //getting the answer 1 or 0 comes from exercise_submit_modal.php
                     $final_answer = $hotspot_delineation_result[1];
                     if ($final_answer == 0) {
                         $questionScore = 0;
                     }
                     // we always insert the answer_id 1 = delineation
                     Event::saveQuestionAttempt($questionScore, 1, $quesId, $exeId, 0);
                     //in delineation mode, get the answer from $hotspot_delineation_result[1]
                     Event::saveExerciseAttemptHotspot($exeId, $quesId, 1, $hotspot_delineation_result[1], $exerciseResultCoordinates[$quesId]);
                 } else {
                     if ($final_answer == 0) {
                         $questionScore = 0;
                         $answer = 0;
                         Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0);
                         if (is_array($exerciseResultCoordinates[$quesId])) {
                             foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) {
                                 Event::saveExerciseAttemptHotspot($exeId, $quesId, $idx, 0, $val);
                             }
                         }
                     } else {
                         Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0);
                         if (is_array($exerciseResultCoordinates[$quesId])) {
                             foreach ($exerciseResultCoordinates[$quesId] as $idx => $val) {
                                 Event::saveExerciseAttemptHotspot($exeId, $quesId, $idx, $choice[$idx], $val);
                             }
                         }
                     }
                 }
                 $my_exe_id = $exeId;
             }
         }
         if ($answerType == HOT_SPOT || $answerType == HOT_SPOT_ORDER) {
             // We made an extra table for the answers
             if ($show_result) {
                 //	if ($origin != 'learnpath') {
                 echo '</table></td></tr>';
                 echo "\n                        <tr>\n                            <td colspan=\"2\">\n                                <p><em>" . get_lang('HotSpot') . "</em></p>\n                                <div id=\"hotspot-solution-{$questionId}\"></div>\n\n                                <script>\n                                    \$(document).on('ready', function () {\n                                        new HotspotQuestion({\n                                            questionId: {$questionId},\n                                            exerciseId: {$exeId},\n                                            selector: '#hotspot-solution-{$questionId}',\n                                            for: 'solution'\n                                        });\n                                    });\n                                </script>\n                            </td>\n                        </tr>\n                    ";
                 //	}
             }
         }
         //if ($origin != 'learnpath') {
         if ($show_result) {
             echo '</table>';
         }
         //	}
     }
     unset($objAnswerTmp);
     $totalWeighting += $questionWeighting;
     // Store results directly in the database
     // For all in one page exercises, the results will be
     // stored by exercise_results.php (using the session)
     if ($saved_results) {
         if ($debug) {
             error_log("Save question results {$saved_results}");
         }
         if ($debug) {
             error_log(print_r($choice, 1));
         }
         if (empty($choice)) {
             $choice = 0;
         }
         if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
             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);
                     if ($debug) {
                         error_log('result =>' . $questionScore . ' ' . $ans . ':' . $choice[$ans]);
                     }
                 }
             } else {
                 Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
             }
         } elseif ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
             if ($choice != 0) {
                 $reply = array_keys($choice);
                 if ($debug) {
                     error_log("reply " . print_r($reply, 1) . "");
                 }
                 for ($i = 0; $i < sizeof($reply); $i++) {
                     $ans = $reply[$i];
                     Event::saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
                 }
             } else {
                 Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
             }
         } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
             if ($choice != 0) {
                 $reply = array_keys($choice);
                 for ($i = 0; $i < sizeof($reply); $i++) {
                     $ans = $reply[$i];
                     Event::saveQuestionAttempt($questionScore, $ans, $quesId, $exeId, $i, $this->id);
                 }
             } else {
                 Event::saveQuestionAttempt($questionScore, 0, $quesId, $exeId, 0, $this->id);
             }
         } elseif (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
             if (isset($matching)) {
                 foreach ($matching as $j => $val) {
                     Event::saveQuestionAttempt($questionScore, $val, $quesId, $exeId, $j, $this->id);
                 }
             }
         } elseif ($answerType == FREE_ANSWER) {
             $answer = $choice;
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
         } elseif ($answerType == ORAL_EXPRESSION) {
             $answer = $choice;
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id, $nano);
         } elseif (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION])) {
             $answer = $choice;
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
             //            } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
         } elseif ($answerType == HOT_SPOT) {
             $answer = [];
             if (isset($exerciseResultCoordinates[$questionId]) && !empty($exerciseResultCoordinates[$questionId])) {
                 Database::delete(Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT), ['hotspot_exe_id = ? AND hotspot_question_id = ? AND c_id = ?' => [$exeId, $questionId, api_get_course_int_id()]]);
                 foreach ($exerciseResultCoordinates[$questionId] as $idx => $val) {
                     $answer[] = $val;
                     Event::saveExerciseAttemptHotspot($exeId, $quesId, $idx, $choice[$idx], $val, false, $this->id);
                 }
             }
             Event::saveQuestionAttempt($questionScore, implode('|', $answer), $quesId, $exeId, 0, $this->id);
         } else {
             Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
         }
     }
     if ($propagate_neg == 0 && $questionScore < 0) {
         $questionScore = 0;
     }
     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;
         if ($debug) {
             error_log($sql);
         }
         Database::query($sql);
     }
     $return_array = array('score' => $questionScore, 'weight' => $questionWeighting, 'extra' => $extra_data, 'open_question' => $arrques, 'open_answer' => $arrans, 'answer_type' => $answerType);
     return $return_array;
 }
 /**
  * Restore quiz-questions
  * @params int question id
  */
 function restore_quiz_question($id)
 {
     $resources = $this->course->resources;
     $question = isset($resources[RESOURCE_QUIZQUESTION][$id]) ? $resources[RESOURCE_QUIZQUESTION][$id] : null;
     $new_id = 0;
     if (is_object($question)) {
         if ($question->is_restored()) {
             return $question->destination_id;
         }
         $table_que = Database::get_course_table(TABLE_QUIZ_QUESTION);
         $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
         $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
         // check resources inside html from ckeditor tool and copy correct urls into recipient course
         $question->description = DocumentManager::replace_urls_inside_content_html_from_copy_course($question->description, $this->course->code, $this->course->destination_path);
         $parent_id = 0;
         if (isset($question->parent_info) && !empty($question->parent_info)) {
             $question_obj = Question::readByTitle($question->parent_info['question'], $this->destination_course_id);
             if ($question_obj) {
                 // Reuse media.
                 $parent_id = $question_obj->selectId();
             } else {
                 // Create media.
                 $question_obj = new MediaQuestion();
                 $question_obj->updateCourse($this->destination_course_id);
                 $parent_id = $question_obj->saveMedia(array('questionName' => $question->parent_info['question'], 'questionDescription' => $question->parent_info['description']));
             }
         }
         $sql = "INSERT INTO " . $table_que . " SET\n                    c_id = " . $this->destination_course_id . " ,\n                    question = '" . self::DBUTF8escapestring($question->question) . "',\n                    description = '" . self::DBUTF8escapestring($question->description) . "',\n                    ponderation = '" . self::DBUTF8escapestring($question->ponderation) . "',\n                    position = '" . self::DBUTF8escapestring($question->position) . "',\n                    type='" . self::DBUTF8escapestring($question->quiz_type) . "',\n                    picture='" . self::DBUTF8escapestring($question->picture) . "',\n                    level='" . self::DBUTF8escapestring($question->level) . "',\n                    parent_id = '" . $parent_id . "',\n                    extra='" . self::DBUTF8escapestring($question->extra) . "'";
         Database::query($sql);
         $new_id = Database::insert_id();
         if ($new_id) {
             if (!empty($question->picture)) {
                 $question_temp = Question::read($new_id, $this->destination_course_info['real_id']);
                 $documentPath = api_get_path(SYS_COURSE_PATH) . $this->destination_course_info['path'] . '/document';
                 // picture path
                 $picturePath = $documentPath . '/images';
                 $old_picture = api_get_path(SYS_COURSE_PATH) . $this->course->info['path'] . '/document/images/' . $question->picture;
                 if (file_exists($old_picture)) {
                     $picture_name = 'quiz-' . $new_id . '.jpg';
                     $result = $question_temp->uploadPicture($old_picture, $picture_name, $picturePath);
                     if ($result) {
                         $sql = "UPDATE {$table_que} SET picture = '{$picture_name}' WHERE c_id = " . $this->destination_course_id . " AND id = {$new_id} ";
                         Database::query($sql);
                     }
                 }
             }
         }
         if ($question->type == MATCHING) {
             $temp = array();
             $matching_list = array();
             $matching_to_update = array();
             foreach ($question->answers as $index => $answer) {
                 $temp[$answer['position']] = $answer;
                 if (!empty($answer['correct'])) {
                     $matching_to_update[$answer['iid']] = $answer['correct'];
                 }
             }
             foreach ($temp as $index => $answer) {
                 $sql = "INSERT INTO " . $table_ans . " SET\n                            c_id = " . $this->destination_course_id . " ,\n                            question_id = '" . $new_id . "',\n                            answer = '" . self::DBUTF8escapestring($answer['answer']) . "',\n                            correct = '" . $answer['correct'] . "',\n                            comment = '" . self::DBUTF8escapestring($answer['comment']) . "',\n                            ponderation = '" . $answer['ponderation'] . "',\n                            position = '" . $answer['position'] . "',\n                            hotspot_coordinates = '" . $answer['hotspot_coordinates'] . "',\n                            hotspot_type = '" . $answer['hotspot_type'] . "'";
                 Database::query($sql);
                 $new_answer_id = Database::insert_id();
                 $matching_list[$answer['iid']] = $new_answer_id;
             }
             foreach ($matching_to_update as $old_answer_id => $old_correct_id) {
                 $new_correct = $matching_list[$old_correct_id];
                 $new_fixed_id = $matching_list[$old_answer_id];
                 $sql = "UPDATE {$table_ans} SET correct = '{$new_correct}' WHERE iid = {$new_fixed_id} ";
                 Database::query($sql);
             }
         } else {
             $correct_answers = array();
             foreach ($question->answers as $index => $answer) {
                 // check resources inside html from fckeditor tool and copy correct urls into recipient course
                 $answer['answer'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($answer['answer'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
                 $answer['comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($answer['comment'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
                 $sql = "INSERT INTO " . $table_ans . " SET\n                                c_id = " . $this->destination_course_id . " ,\n                                id = '" . ($index + 1) . "',\n                                question_id = '" . $new_id . "',\n                                answer = '" . self::DBUTF8escapestring($answer['answer']) . "',\n                                correct = '" . $answer['correct'] . "',\n                                comment = '" . self::DBUTF8escapestring($answer['comment']) . "',\n                                ponderation = '" . $answer['ponderation'] . "',\n                                position = '" . $answer['position'] . "',\n                                hotspot_coordinates = '" . $answer['hotspot_coordinates'] . "',\n                                hotspot_type = '" . $answer['hotspot_type'] . "'";
                 Database::query($sql);
                 $new_answer_id = Database::insert_id();
                 $correct_answers[$new_answer_id] = $answer['correct'];
             }
         }
         //Current course id
         $course_id = api_get_course_int_id();
         //Moving quiz_question_options
         if ($question->type == MULTIPLE_ANSWER_TRUE_FALSE) {
             $question_option_list = Question::readQuestionOption($id, $course_id);
             //Question copied from the current platform
             if ($question_option_list) {
                 $old_option_ids = array();
                 foreach ($question_option_list as $item) {
                     $old_id = $item['iid'];
                     unset($item['iid']);
                     $item['question_id'] = $new_id;
                     $item['c_id'] = $this->destination_course_id;
                     $question_option_id = Database::insert($table_options, $item);
                     $old_option_ids[$old_id] = $question_option_id;
                 }
                 if ($old_option_ids) {
                     $new_answers = Database::select('iid, correct', $table_ans, array('WHERE' => array('question_id = ? AND c_id = ? ' => array($new_id, $this->destination_course_id))));
                     foreach ($new_answers as $answer_item) {
                         $params = array();
                         $params['correct'] = $old_option_ids[$answer_item['correct']];
                         $question_option_id = Database::update($table_ans, $params, array('iid = ? AND c_id = ? AND question_id = ? ' => array($answer_item['iid'], $this->destination_course_id, $new_id)), false);
                     }
                 }
             } else {
                 $new_options = array();
                 if (isset($question->question_options)) {
                     foreach ($question->question_options as $obj) {
                         $item = array();
                         $item['question_id'] = $new_id;
                         $item['c_id'] = $this->destination_course_id;
                         $item['name'] = $obj->obj->name;
                         $item['position'] = $obj->obj->position;
                         $question_option_id = Database::insert($table_options, $item);
                         $new_options[$obj->obj->iid] = $question_option_id;
                     }
                     foreach ($correct_answers as $answer_id => $correct_answer) {
                         $params = array();
                         $params['correct'] = $new_options[$correct_answer];
                         Database::update($table_ans, $params, array('iid = ? AND c_id = ? AND question_id = ? ' => array($answer_id, $this->destination_course_id, $new_id)), false);
                     }
                 }
             }
         }
         if ($question->categories) {
             $cats = array();
             foreach ($question->categories as $cat) {
                 $new_category = new Testcategory($cat['category_id']);
                 $new_category = $new_category->get_category_by_title($cat['title'], $this->destination_course_id);
                 if (empty($new_category)) {
                     //Create a new category in this portal
                     if ($cat['category_id'] == 0) {
                         $category_c_id = 0;
                     } else {
                         $category_c_id = $this->destination_course_id;
                     }
                     $new_cat = new Testcategory(null, $cat['title'], $cat['description'], null, 'simple', $category_c_id);
                     $new_cat_id = $new_cat->addCategoryInBDD();
                     $cats[] = $new_cat_id;
                 } else {
                     $cats[] = $new_category['iid'];
                 }
             }
             $question = Question::read($new_id, $this->destination_course_id);
             if (!empty($cats)) {
                 $question->saveCategories($cats);
             }
         }
         $this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
     }
     return $new_id;
 }
Exemplo n.º 3
0
    /**
     * Shows a question
     *
     * @param int    $questionId question id
     * @param bool   $only_questions if true only show the questions, no exercise title
     * @param bool   $origin  i.e = learnpath
     * @param string $current_item current item from the list of questions
     * @param bool   $show_title
     * @param bool   $freeze
     * @param array  $user_choice
     * @param bool   $show_comment
     * @param bool   $exercise_feedback
     * @param bool   $show_answers
     * */
    public static function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false)
    {
        $course_id = api_get_course_int_id();
        // Change false to true in the following line to enable answer hinting
        $debug_mark_answer = $show_answers;
        // Reads question information
        if (!($objQuestionTmp = Question::read($questionId))) {
            // Question not found
            return false;
        }
        if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) {
            $show_comment = false;
        }
        $answerType = $objQuestionTmp->selectType();
        $pictureName = $objQuestionTmp->selectPicture();
        $s = '';
        if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) {
            // Question is not a hotspot
            if (!$only_questions) {
                $questionDescription = $objQuestionTmp->selectDescription();
                if ($show_title) {
                    TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
                    echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title'));
                }
                if (!empty($questionDescription)) {
                    echo Display::div($questionDescription, array('class' => 'question_description'));
                }
            }
            if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) {
                return '';
            }
            echo '<div class="question_options row">';
            // construction of the Answer object (also gets all answers details)
            $objAnswerTmp = new Answer($questionId);
            $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
            $quiz_question_options = Question::readQuestionOption($questionId, $course_id);
            // For "matching" type here, we need something a little bit special
            // because the match between the suggestions and the answers cannot be
            // done easily (suggestions and answers are in the same table), so we
            // have to go through answers first (elems with "correct" value to 0).
            $select_items = array();
            //This will contain the number of answers on the left side. We call them
            // suggestions here, for the sake of comprehensions, while the ones
            // on the right side are called answers
            $num_suggestions = 0;
            if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
                if ($answerType == DRAGGABLE) {
                    $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix">
                        <div class="clearfix">
                        <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">';
                } else {
                    $s .= <<<HTML
                        <div id="drag{$questionId}_question" class="drag_question">
                            <table class="data_table">
HTML;
                }
                // Iterate through answers
                $x = 1;
                //mark letters for each answer
                $letter = 'A';
                $answer_matching = array();
                $cpt1 = array();
                for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                    $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                    $numAnswer = $objAnswerTmp->selectAutoId($answerId);
                    if ($answerCorrect == 0) {
                        // options (A, B, C, ...) that will be put into the list-box
                        // have the "correct" field set to 0 because they are answer
                        $cpt1[$x] = $letter;
                        $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer);
                        $x++;
                        $letter++;
                    }
                }
                $i = 1;
                $select_items[0]['id'] = 0;
                $select_items[0]['letter'] = '--';
                $select_items[0]['answer'] = '';
                foreach ($answer_matching as $id => $value) {
                    $select_items[$i]['id'] = $value['id'];
                    $select_items[$i]['letter'] = $cpt1[$id];
                    $select_items[$i]['answer'] = $value['answer'];
                    $i++;
                }
                $user_choice_array_position = array();
                if (!empty($user_choice)) {
                    foreach ($user_choice as $item) {
                        $user_choice_array_position[$item['position']] = $item['answer'];
                    }
                }
                $num_suggestions = $nbrAnswers - $x + 1;
            } elseif ($answerType == FREE_ANSWER) {
                $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null;
                $form = new FormValidator('free_choice_' . $questionId);
                $config = array('ToolbarSet' => 'TestFreeAnswer');
                $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config);
                $form->setDefaults(array("choice[" . $questionId . "]" => $fck_content));
                $s .= $form->returnForm();
            } elseif ($answerType == ORAL_EXPRESSION) {
                // Add nanog
                if (api_get_setting('enable_nanogong') == 'true') {
                    //@todo pass this as a parameter
                    global $exercise_stat_info, $exerciseId, $exe_id;
                    if (!empty($exercise_stat_info)) {
                        $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId);
                    } else {
                        $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId);
                    }
                    $nano = new Nanogong($params);
                    echo $nano->show_button();
                }
                $form = new FormValidator('free_choice_' . $questionId);
                $config = array('ToolbarSet' => 'TestFreeAnswer');
                $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config);
                //$form->setDefaults(array("choice[" . $questionId . "]" => $fck_content));
                $s .= $form->return_form();
            }
            // Now navigate through the possible answers, using the max number of
            // answers for the question as a limiter
            $lines_count = 1;
            // a counter for matching-type answers
            if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                $header = Display::tag('th', get_lang('Options'));
                foreach ($objQuestionTmp->options as $item) {
                    if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                        if (in_array($item, $objQuestionTmp->options)) {
                            $header .= Display::tag('th', get_lang($item));
                        } else {
                            $header .= Display::tag('th', $item);
                        }
                    } else {
                        $header .= Display::tag('th', $item);
                    }
                }
                if ($show_comment) {
                    $header .= Display::tag('th', get_lang('Feedback'));
                }
                $s .= '<table class="table table-hover table-striped">';
                $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
            }
            if ($show_comment) {
                if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) {
                    $header = Display::tag('th', get_lang('Options'));
                    if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) {
                        $header .= Display::tag('th', get_lang('Feedback'));
                    }
                    $s .= '<table class="table table-hover table-striped">';
                    $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
                }
            }
            $matching_correct_answer = 0;
            $user_choice_array = array();
            if (!empty($user_choice)) {
                foreach ($user_choice as $item) {
                    $user_choice_array[] = $item['answer'];
                }
            }
            for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                $answer = $objAnswerTmp->selectAnswer($answerId);
                $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                $numAnswer = $objAnswerTmp->selectAutoId($answerId);
                $comment = $objAnswerTmp->selectComment($answerId);
                $attributes = array();
                // Unique answer
                if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) {
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    if ($show_comment) {
                        $s .= '<tr><td>';
                    }
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        if ($show_comment) {
                            if (empty($comment)) {
                                $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image" style="text-align: center">';
                            } else {
                                $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-sm-12" style="text-align: center">';
                            }
                        } else {
                            $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-md-3" style="text-align: center">';
                        }
                    }
                    $answer = Security::remove_XSS($answer, STUDENT);
                    $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0');
                    $answer_input = null;
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        $attributes['style'] = 'display: none;';
                        $answer = '<div class="thumbnail">' . $answer . '</div>';
                    }
                    $answer_input .= '<label class="radio">';
                    $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        $answer_input .= "</div>";
                    }
                    if ($show_comment) {
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    $answer = Security::remove_XSS($answer, STUDENT);
                    if (in_array($numAnswer, $user_choice_array)) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                        $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                        $answer_input = '<label class="checkbox">';
                        $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes);
                        $answer_input .= $answer;
                        $answer_input .= '</label>';
                        if ($show_comment) {
                            $s .= '<tr><td>';
                            $s .= $answer_input;
                            $s .= '</td>';
                            $s .= '<td>';
                            $s .= $comment;
                            $s .= '</td>';
                            $s .= '</tr>';
                        } else {
                            $s .= $answer_input;
                        }
                    } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                        $my_choice = array();
                        if (!empty($user_choice_array)) {
                            foreach ($user_choice_array as $item) {
                                $item = explode(':', $item);
                                $my_choice[$item[0]] = $item[1];
                            }
                        }
                        $s .= '<tr>';
                        $s .= Display::tag('td', $answer);
                        if (!empty($quiz_question_options)) {
                            foreach ($quiz_question_options as $id => $item) {
                                if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) {
                                    $attributes = array('checked' => 1, 'selected' => 1);
                                } else {
                                    $attributes = array();
                                }
                                if ($debug_mark_answer) {
                                    if ($id == $answerCorrect) {
                                        $attributes['checked'] = 1;
                                        $attributes['selected'] = 1;
                                    }
                                }
                                $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => ''));
                            }
                        }
                        if ($show_comment) {
                            $s .= '<td>';
                            $s .= $comment;
                            $s .= '</td>';
                        }
                        $s .= '</tr>';
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
                    // multiple answers
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    if (in_array($numAnswer, $user_choice_array)) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    $answer = Security::remove_XSS($answer, STUDENT);
                    $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $answer_input .= '<label class="checkbox">';
                    $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($show_comment) {
                        $s .= '<tr>';
                        $s .= '<td>';
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                    $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $my_choice = array();
                    if (!empty($user_choice_array)) {
                        foreach ($user_choice_array as $item) {
                            $item = explode(':', $item);
                            if (isset($item[1]) && isset($item[0])) {
                                $my_choice[$item[0]] = $item[1];
                            }
                        }
                    }
                    $answer = Security::remove_XSS($answer, STUDENT);
                    $s .= '<tr>';
                    $s .= Display::tag('td', $answer);
                    foreach ($objQuestionTmp->options as $key => $item) {
                        if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) {
                            $attributes = array('checked' => 1, 'selected' => 1);
                        } else {
                            $attributes = array();
                        }
                        if ($debug_mark_answer) {
                            if ($key == $answerCorrect) {
                                $attributes['checked'] = 1;
                                $attributes['selected'] = 1;
                            }
                        }
                        $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes));
                    }
                    if ($show_comment) {
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                    }
                    $s .= '</tr>';
                } elseif ($answerType == FILL_IN_BLANKS) {
                    // display the question, with field empty, for student to fill it,
                    // or filled to display the answer in the Question preview of the exercice/admin.php page
                    $displayForStudent = true;
                    $listAnswerInformations = FillBlanks::getAnswerInfo($answer);
                    $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']);
                    $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']);
                    list($answer) = explode('::', $answer);
                    //Correct answers
                    $correctAnswerList = $listAnswerInformations['tabwords'];
                    //Student's answer
                    $studentAnswerList = array();
                    if (isset($user_choice[0]['answer'])) {
                        $arrayStudentAnswer = FillBlanks::getAnswerInfo($user_choice[0]['answer'], true);
                        $studentAnswerList = $arrayStudentAnswer['studentanswer'];
                    }
                    // If the question must be shown with the answer (in page exercice/admin.php) for teacher preview
                    // set the student-answer to the correct answer
                    if ($debug_mark_answer) {
                        $studentAnswerList = $correctAnswerList;
                        $displayForStudent = false;
                    }
                    if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
                        $answer = "";
                        for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) {
                            // display the common word
                            $answer .= $listAnswerInformations["commonwords"][$i];
                            // display the blank word
                            $correctItem = $listAnswerInformations["tabwords"][$i];
                            $correctItemRegexp = $correctItem;
                            // replace / with \/ to allow the preg_replace bellow and all the regexp char
                            $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp);
                            if (isset($studentAnswerList[$i])) {
                                // If student already started this test and answered this question,
                                // fill the blank with his previous answers
                                // may be "" if student viewed the question, but did not fill the blanks
                                $correctItem = $studentAnswerList[$i];
                            }
                            $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px";
                            $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, $correctItem, $attributes, $answer, $listAnswerInformations, $displayForStudent, $i);
                        }
                        // display the last common word
                        $answer .= $listAnswerInformations["commonwords"][$i];
                    } else {
                        // display empty [input] with the right width for student to fill it
                        $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']);
                        $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']);
                        $answer = "";
                        for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) {
                            // display the common words
                            $answer .= $listAnswerInformations["commonwords"][$i];
                            // display the blank word
                            $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px";
                            $correctItem = $listAnswerInformations["tabwords"][$i];
                            $correctItemRegexp = $correctItem;
                            // replace / with \/ to allow the preg_replace bellow and all the regexp char
                            $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp);
                            $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, '', $attributes, $answer, $listAnswerInformations, $displayForStudent, $i);
                        }
                        // display the last common word
                        $answer .= $listAnswerInformations["commonwords"][$i];
                    }
                    $s .= $answer;
                } elseif ($answerType == CALCULATED_ANSWER) {
                    /*
                     * In the CALCULATED_ANSWER test
                     * you mustn't have [ and ] in the textarea
                     * you mustn't have @@ in the textarea
                     * the text to find mustn't be empty or contains only spaces
                     * the text to find mustn't contains HTML tags
                     * the text to find mustn't contains char "
                     */
                    if ($origin !== null) {
                        global $exe_id;
                        $trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
                        $sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . '
                                            WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId;
                        $rsLastAttempt = Database::query($sqlTrackAttempt);
                        $rowLastAttempt = Database::fetch_array($rsLastAttempt);
                        $answer = $rowLastAttempt['answer'];
                        if (empty($answer)) {
                            $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers);
                            $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
                        }
                    }
                    list($answer) = explode('@@', $answer);
                    // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]]
                    api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList);
                    // 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('/\\[[^]]+\\]/', $answer, $studentAnswerList);
                        $studentAnswerListTobecleaned = $studentAnswerList[0];
                        $studentAnswerList = array();
                        for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) {
                            $answerCorrected = $studentAnswerListTobecleaned[$i];
                            $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected);
                            $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected);
                            $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected);
                            $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected);
                            $answerCorrected = '[' . $answerCorrected . ']';
                            $studentAnswerList[] = $answerCorrected;
                        }
                    }
                    // 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];
                    }
                    /*
                    Split the response by bracket
                    tabComments is an array with text surrounding the text to find
                    we add a space before and after the answerQuestion to be sure to
                    have a block of text before and after [xxx] patterns
                    so we have n text to find ([xxx]) and n+1 block of texts before,
                    between and after the text to find
                    */
                    $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' ');
                    if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
                        $answer = "";
                        $i = 0;
                        foreach ($studentAnswerList as $studentItem) {
                            // remove surronding brackets
                            $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2);
                            $size = strlen($studentItem);
                            $attributes['class'] = self::detectInputAppropriateClass($size);
                            $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes);
                            $i++;
                        }
                        $answer .= $tabComments[$i];
                    } else {
                        // display exercise with empty input fields
                        // every [xxx] are replaced with an empty input field
                        foreach ($correctAnswerList[0] as $item) {
                            $size = strlen($item);
                            $attributes['class'] = self::detectInputAppropriateClass($size);
                            $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer);
                        }
                    }
                    if ($origin !== null) {
                        $s = $answer;
                        break;
                    } else {
                        $s .= $answer;
                    }
                } elseif ($answerType == MATCHING) {
                    // matching type, showing suggestions and answers
                    // TODO: replace $answerId by $numAnswer
                    if ($answerCorrect != 0) {
                        // only show elements to be answered (not the contents of
                        // the select boxes, who are corrrect = 0)
                        $s .= '<tr><td width="45%" valign="top">';
                        $parsed_answer = $answer;
                        //left part questions
                        $s .= '<p class="indent">' . $lines_count . '.&nbsp;' . $parsed_answer . '</p></td>';
                        //middle part (matches selects)
                        $s .= '<td width="10%" valign="top" align="center" >
                                <div class="select-matching">
                                <select name="choice[' . $questionId . '][' . $numAnswer . ']">';
                        // fills the list-box
                        foreach ($select_items as $key => $val) {
                            // set $debug_mark_answer to true at function start to
                            // show the correct answer with a suffix '-x'
                            $selected = '';
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selected = 'selected="selected"';
                                }
                            }
                            //$user_choice_array_position
                            if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) {
                                $selected = 'selected="selected"';
                            }
                            $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>';
                        }
                        // end foreach()
                        $s .= '</select></div></td><td width="5%" class="separate">&nbsp;</td>';
                        $s .= '<td width="40%" valign="top" >';
                        if (isset($select_items[$lines_count])) {
                            $s .= '<div class="text-right"><p class="indent">' . $select_items[$lines_count]['letter'] . '.&nbsp; ' . $select_items[$lines_count]['answer'] . '</p></div>';
                        } else {
                            $s .= '&nbsp;';
                        }
                        $s .= '</td>';
                        $s .= '</tr>';
                        $lines_count++;
                        //if the left side of the "matching" has been completely
                        // shown but the right side still has values to show...
                        if ($lines_count - 1 == $num_suggestions) {
                            // if it remains answers to shown at the right side
                            while (isset($select_items[$lines_count])) {
                                $s .= '<tr>
                                      <td colspan="2"></td>
                                      <td valign="top">';
                                $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'];
                                $s .= "</td>\n                                </tr>";
                                $lines_count++;
                            }
                            // end while()
                        }
                        // end if()
                        $matching_correct_answer++;
                    }
                } elseif ($answerType == DRAGGABLE) {
                    if ($answerCorrect != 0) {
                        $parsed_answer = $answer;
                        /*$lines_count = '';
                          $data = $objAnswerTmp->getAnswerByAutoId($numAnswer);
                          $data = $objAnswerTmp->getAnswerByAutoId($data['correct']);
                          $lines_count = $data['answer'];*/
                        $windowId = $questionId . '_' . $lines_count;
                        $s .= '<li class="touch-items" id="' . $windowId . '">';
                        $s .= Display::div($parsed_answer, ['id' => "window_{$windowId}", 'class' => "window{$questionId}_question_draggable exercise-draggable-answer-option"]);
                        $selectedValue = 0;
                        $draggableSelectOptions = [];
                        foreach ($select_items as $key => $val) {
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selectedValue = $val['id'];
                                }
                            }
                            if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
                                $selectedValue = $val['id'];
                            }
                            $draggableSelectOptions[$val['id']] = $val['letter'];
                        }
                        $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $draggableSelectOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'select_option', 'style' => 'display: none;'], false);
                        if (!empty($answerCorrect) && !empty($selectedValue)) {
                            $s .= <<<JAVASCRIPT
                                <script>
                                    \$(function() {
                                        DraggableAnswer.deleteItem(
                                            \$('#{$questionId}_{$selectedValue}'),
                                            \$('#drop_{$windowId}')
                                        );
                                    });
                                </script>
JAVASCRIPT;
                        }
                        if (isset($select_items[$lines_count])) {
                            $s .= Display::div(Display::tag('b', $select_items[$lines_count]['letter']) . $select_items[$lines_count]['answer'], ['id' => "window_{$windowId}_answer", 'style' => 'display: none;']);
                        } else {
                            $s .= '&nbsp;';
                        }
                        $lines_count++;
                        if ($lines_count - 1 == $num_suggestions) {
                            while (isset($select_items[$lines_count])) {
                                $s .= Display::tag('b', $select_items[$lines_count]['letter']);
                                $s .= $select_items[$lines_count]['answer'];
                                $lines_count++;
                            }
                        }
                        $matching_correct_answer++;
                        $s .= '</li>';
                    }
                } elseif ($answerType == MATCHING_DRAGGABLE) {
                    if ($answerId == 1) {
                        echo $objAnswerTmp->getJs();
                    }
                    if ($answerCorrect != 0) {
                        $parsed_answer = $answer;
                        $windowId = "{$questionId}_{$lines_count}";
                        $s .= <<<HTML
                            <tr>
                                <td widht="45%">
                                    <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question">
                                        <strong>{$lines_count}.</strong> {$parsed_answer}
                                    </div>
                                </td>
                                <td width="10%">
HTML;
                        $selectedValue = 0;
                        $questionOptions = [];
                        foreach ($select_items as $key => $val) {
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selectedValue = $val['id'];
                                }
                            }
                            if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
                                $selectedValue = $val['id'];
                            }
                            $questionOptions[$val['id']] = $val['letter'];
                        }
                        $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $questionOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'hidden'], false);
                        if (!empty($answerCorrect) && !empty($selectedValue)) {
                            // Show connect if is not freeze (question preview)
                            if (!$freeze) {
                                $s .= <<<JAVASCRIPT
                                <script>
                                    jsPlumb.ready(function() {
                                        jsPlumb.connect({
                                            source: 'window_{$windowId}',
                                            target: 'window_{$questionId}_{$selectedValue}_answer',
                                            endpoint: ['Blank', {radius: 15}],
                                            anchors: ['RightMiddle', 'LeftMiddle'],
                                            paintStyle: {strokeStyle: '#8A8888', lineWidth: 8},
                                            connector: [
                                                MatchingDraggable.connectorType,
                                                {curvines: MatchingDraggable.curviness}
                                            ]
                                        });
                                    });
                                </script>
JAVASCRIPT;
                            }
                        }
                        $s .= <<<HTML
                            </td>
                            <td width="45%">
HTML;
                        if (isset($select_items[$lines_count])) {
                            $s .= <<<HTML
                                <div id="window_{$windowId}_answer" class="window window_right_question">
                                    <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']}
                                </div>
HTML;
                        } else {
                            $s .= '&nbsp;';
                        }
                        $s .= '</td></tr>';
                        $lines_count++;
                        if ($lines_count - 1 == $num_suggestions) {
                            while (isset($select_items[$lines_count])) {
                                $s .= <<<HTML
                                    <tr>
                                        <td colspan="2"></td>
                                        <td>
                                            <strong>{$select_items[$lines_count]['letter']}</strong>
                                            {$select_items[$lines_count]['answer']}
                                        </td>
                                    </tr>
HTML;
                                $lines_count++;
                            }
                        }
                        $matching_correct_answer++;
                    }
                }
            }
            // end for()
            if ($show_comment) {
                $s .= '</table>';
            } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE])) {
                $s .= '</table>';
            }
            if ($answerType == DRAGGABLE) {
                $s .= "</ul></div>";
                $counterAnswer = 1;
                $s .= '<div class="col-md-12"><div class="row">';
                for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                    $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                    $windowId = $questionId . '_' . $counterAnswer;
                    if ($answerCorrect) {
                        $s .= Display::div($counterAnswer, ['id' => "drop_{$windowId}", 'class' => 'droppable col-md-2']);
                        $counterAnswer++;
                    }
                }
                $s .= '</div></div>';
            }
            if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                $s .= '</div>';
            }
            $s .= '</div>';
            // destruction of the Answer object
            unset($objAnswerTmp);
            // destruction of the Question object
            unset($objQuestionTmp);
            if ($origin != 'export') {
                echo $s;
            } else {
                return $s;
            }
        } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
            // Question is a HOT_SPOT
            //checking document/images visibility
            if (api_is_platform_admin() || api_is_course_admin()) {
                $course = api_get_course_info();
                $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName);
                if (is_numeric($doc_id)) {
                    $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id());
                    if (!$images_folder_visibility) {
                        //This message is shown only to the course/platform admin if the image is set to visibility = false
                        Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage'));
                    }
                }
            }
            $questionName = $objQuestionTmp->selectTitle();
            $questionDescription = $objQuestionTmp->selectDescription();
            if ($freeze) {
                echo Display::img($objQuestionTmp->selectPicturePath());
                return;
            }
            // Get the answers, make a list
            $objAnswerTmp = new Answer($questionId);
            $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
            // get answers of hotpost
            $answers_hotspot = array();
            for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId));
                $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId);
            }
            // display answers of hotpost order by id
            $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>';
            if (!empty($answers_hotspot)) {
                ksort($answers_hotspot);
                foreach ($answers_hotspot as $key => $value) {
                    $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />';
                }
            }
            $answer_list .= '</dl></div>';
            if ($answerType == HOT_SPOT_DELINEATION) {
                $answer_list = '';
                $swf_file = 'hotspot_delineation_user';
                $swf_height = 405;
            } else {
                $swf_file = 'hotspot_user';
                $swf_height = 436;
            }
            if (!$only_questions) {
                if ($show_title) {
                    TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
                    echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>';
                }
                //@todo I need to the get the feedback type
                echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />';
                echo '<table class="exercise_questions" >
                      <tr>
                        <td valign="top" colspan="2">';
                echo $questionDescription;
                echo '</td></tr>';
            }
            $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
            $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
                            <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script>
                            <script type="text/javascript">
                            <!--
                            // Globals
                            // Major version of Flash required
                            var requiredMajorVersion = 7;
                            // Minor version of Flash required
                            var requiredMinorVersion = 0;
                            // Minor version of Flash required
                            var requiredRevision = 0;
                            // the version of javascript supported
                            var jsVersion = 1.0;
                            // -->
                            </script>
                            <script language="VBScript" type="text/vbscript">
                            <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
                            Function VBGetSwfVer(i)
                              on error resume next
                              Dim swControl, swVersion
                              swVersion = 0

                              set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))
                              if (IsObject(swControl)) then
                                swVersion = swControl.GetVariable("$version")
                              end if
                              VBGetSwfVer = swVersion
                            End Function
                            // -->
                            </script>

                            <script language="JavaScript1.1" type="text/javascript">
                            <!-- // Detect Client Browser type
                            var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
                            var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
                            var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
                            jsVersion = 1.1;
                            // JavaScript helper required to detect Flash Player PlugIn version information
                            function JSGetSwfVer(i) {
                                // NS/Opera version >= 3 check for Flash plugin in plugin array
                                if (navigator.plugins != null && navigator.plugins.length > 0) {
                                    if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
                                        var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
                                        var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
                                        descArray = flashDescription.split(" ");
                                        tempArrayMajor = descArray[2].split(".");
                                        versionMajor = tempArrayMajor[0];
                                        versionMinor = tempArrayMajor[1];
                                        if ( descArray[3] != "" ) {
                                            tempArrayMinor = descArray[3].split("r");
                                        } else {
                                            tempArrayMinor = descArray[4].split("r");
                                        }
                                        versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
                                        flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
                                    } else {
                                        flashVer = -1;
                                    }
                                }
                                // MSN/WebTV 2.6 supports Flash 4
                                else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
                                // WebTV 2.5 supports Flash 3
                                else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
                                // older WebTV supports Flash 2
                                else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
                                // Can\'t detect in all other cases
                                else
                                {
                                    flashVer = -1;
                                }
                                return flashVer;
                            }
                            // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available

                            function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
                                reqVer = parseFloat(reqMajorVer + "." + reqRevision);
                                // loop backwards through the versions until we find the newest version
                                for (i=25;i>0;i--) {
                                    if (isIE && isWin && !isOpera) {
                                        versionStr = VBGetSwfVer(i);
                                    } else {
                                        versionStr = JSGetSwfVer(i);
                                    }
                                    if (versionStr == -1 ) {
                                        return false;
                                    } else if (versionStr != 0) {
                                        if(isIE && isWin && !isOpera) {
                                            tempArray         = versionStr.split(" ");
                                            tempString        = tempArray[1];
                                            versionArray      = tempString .split(",");
                                        } else {
                                            versionArray      = versionStr.split(".");
                                        }
                                        versionMajor      = versionArray[0];
                                        versionMinor      = versionArray[1];
                                        versionRevision   = versionArray[2];

                                        versionString     = versionMajor + "." + versionRevision;   // 7.0r24 == 7.24
                                        versionNum        = parseFloat(versionString);
                                        // is the major.revision >= requested major.revision AND the minor version >= requested minor
                                        if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
                                            return true;
                                        } else {
                                            return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
                                        }
                                    }
                                }
                            }
                            // -->
                            </script>';
            $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520">
                        <script>
                            <!--
                            // Version check based upon the values entered above in "Globals"
                            var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);

                            // Check to see if the version meets the requirements for playback
                            if (hasReqestedVersion) {  // if we\'ve detected an acceptable version
                                var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\'
                                            + \'<param name="wmode" value="transparent">\'
                                            + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\'
                                            + \'<\\/object>\';
                                document.write(oeTags);   // embed the Flash Content SWF when all tests are passed
                            } else {  // flash is too old or we can\'t detect the plugin
                                var alternateContent = "Error<br \\/>"
                                    + "Hotspots requires Macromedia Flash 7.<br \\/>"
                                    + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>";
                                document.write(alternateContent);  // insert non-flash content
                            }
                            // -->
                        </script>
                        </td>
                        <td valign="top" align="left">' . $answer_list . '</td></tr>
                        </table>
            </td></tr>';
            echo $s;
            echo '</table>';
        }
        return $nbrAnswers;
    }
Exemplo n.º 4
0
    /**
     * Shows a question
     *
     * @param int    $questionId question id
     * @param bool   $only_questions if true only show the questions, no exercise title
     * @param bool   $origin  i.e = learnpath
     * @param string $current_item current item from the list of questions
     * @param bool   $show_title
     * @param bool   $freeze
     * @param array  $user_choice
     * @param bool   $show_comment
     * @param bool   $exercise_feedback
     * @param bool   $show_answers
     * */
    public static function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false)
    {
        $course_id = api_get_course_int_id();
        // Change false to true in the following line to enable answer hinting
        $debug_mark_answer = $show_answers;
        // Reads question information
        if (!($objQuestionTmp = Question::read($questionId))) {
            // Question not found
            return false;
        }
        if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) {
            $show_comment = false;
        }
        $answerType = $objQuestionTmp->selectType();
        $pictureName = $objQuestionTmp->selectPicture();
        $s = '';
        if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) {
            // Question is not a hotspot
            if (!$only_questions) {
                $questionDescription = $objQuestionTmp->selectDescription();
                if ($show_title) {
                    TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
                    echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title'));
                }
                if (!empty($questionDescription)) {
                    echo Display::div($questionDescription, array('class' => 'question_description'));
                }
            }
            if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) {
                return '';
            }
            echo '<div class="question_options row">';
            // construction of the Answer object (also gets all answers details)
            $objAnswerTmp = new Answer($questionId);
            $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
            $quiz_question_options = Question::readQuestionOption($questionId, $course_id);
            // For "matching" type here, we need something a little bit special
            // because the match between the suggestions and the answers cannot be
            // done easily (suggestions and answers are in the same table), so we
            // have to go through answers first (elems with "correct" value to 0).
            $select_items = array();
            //This will contain the number of answers on the left side. We call them
            // suggestions here, for the sake of comprehensions, while the ones
            // on the right side are called answers
            $num_suggestions = 0;
            if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
                if ($answerType == DRAGGABLE) {
                    $s .= '<div class="col-md-12 ui-widget ui-helper-clearfix">
                        <div class="clearfix">
                        <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">';
                } else {
                    $s .= '<div id="drag' . $questionId . '_question" class="drag_question">
                           <table class="data_table">';
                }
                // Iterate through answers
                $x = 1;
                //mark letters for each answer
                $letter = 'A';
                $answer_matching = array();
                $cpt1 = array();
                for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                    $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                    $numAnswer = $objAnswerTmp->selectAutoId($answerId);
                    if ($answerCorrect == 0) {
                        // options (A, B, C, ...) that will be put into the list-box
                        // have the "correct" field set to 0 because they are answer
                        $cpt1[$x] = $letter;
                        $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer);
                        $x++;
                        $letter++;
                    }
                }
                $i = 1;
                $select_items[0]['id'] = 0;
                $select_items[0]['letter'] = '--';
                $select_items[0]['answer'] = '';
                foreach ($answer_matching as $id => $value) {
                    $select_items[$i]['id'] = $value['id_auto'];
                    $select_items[$i]['letter'] = $cpt1[$id];
                    $select_items[$i]['answer'] = $value['answer'];
                    $i++;
                }
                $user_choice_array_position = array();
                if (!empty($user_choice)) {
                    foreach ($user_choice as $item) {
                        $user_choice_array_position[$item['position']] = $item['answer'];
                    }
                }
                $num_suggestions = $nbrAnswers - $x + 1;
            } elseif ($answerType == FREE_ANSWER) {
                $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null;
                $form = new FormValidator('free_choice_' . $questionId);
                $config = array('ToolbarSet' => 'TestFreeAnswer');
                $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config);
                $form->setDefaults(array("choice[" . $questionId . "]" => $fck_content));
                $s .= $form->returnForm();
            } elseif ($answerType == ORAL_EXPRESSION) {
                // Add nanog
                if (api_get_setting('document.enable_nanogong') == 'true') {
                    //@todo pass this as a parameter
                    global $exercise_stat_info, $exerciseId, $exe_id;
                    if (!empty($exercise_stat_info)) {
                        $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId);
                    } else {
                        $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId);
                    }
                    $nano = new Nanogong($params);
                    echo $nano->show_button();
                }
                $form = new FormValidator('free_choice_' . $questionId);
                $config = array('ToolbarSet' => 'TestFreeAnswer');
                $form->addHtmlEditor("choice[" . $questionId . "]", null, false, false, $config);
                //$form->setDefaults(array("choice[" . $questionId . "]" => $fck_content));
                $s .= $form->returnForm();
            }
            // Now navigate through the possible answers, using the max number of
            // answers for the question as a limiter
            $lines_count = 1;
            // a counter for matching-type answers
            if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                $header = Display::tag('th', get_lang('Options'));
                foreach ($objQuestionTmp->options as $item) {
                    if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                        if (in_array($item, $objQuestionTmp->options)) {
                            $header .= Display::tag('th', get_lang($item));
                        } else {
                            $header .= Display::tag('th', $item);
                        }
                    } else {
                        $header .= Display::tag('th', $item);
                    }
                }
                if ($show_comment) {
                    $header .= Display::tag('th', get_lang('Feedback'));
                }
                $s .= '<table class="table table-hover table-striped">';
                $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
            }
            if ($show_comment) {
                if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) {
                    $header = Display::tag('th', get_lang('Options'));
                    if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) {
                        $header .= Display::tag('th', get_lang('Feedback'));
                    }
                    $s .= '<table class="table table-hover table-striped">';
                    $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
                }
            }
            $matching_correct_answer = 0;
            $user_choice_array = array();
            if (!empty($user_choice)) {
                foreach ($user_choice as $item) {
                    $user_choice_array[] = $item['answer'];
                }
            }
            for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                $answer = $objAnswerTmp->selectAnswer($answerId);
                $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                $numAnswer = $objAnswerTmp->selectAutoId($answerId);
                $comment = $objAnswerTmp->selectComment($answerId);
                $attributes = array();
                // Unique answer
                if (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, UNIQUE_ANSWER_IMAGE])) {
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    if ($show_comment) {
                        $s .= '<tr><td>';
                    }
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        if ($show_comment) {
                            if (empty($comment)) {
                                $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image" style="text-align: center">';
                            } else {
                                $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-sm-12" style="text-align: center">';
                            }
                        } else {
                            $s .= '<div id="answer' . $questionId . $numAnswer . '" ' . 'class="exercise-unique-answer-image col-xs-6 col-md-3" style="text-align: center">';
                        }
                    }
                    $answer = Security::remove_XSS($answer, STUDENT);
                    $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0');
                    $answer_input = null;
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        $attributes['style'] = 'display: none;';
                        $answer = '<div class="thumbnail">' . $answer . '</div>';
                    }
                    $answer_input .= '<label class="radio">';
                    $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        $answer_input .= "</div>";
                    }
                    if ($show_comment) {
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    $answer = Security::remove_XSS($answer, STUDENT);
                    if (in_array($numAnswer, $user_choice_array)) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                        $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                        $answer_input = '<label class="checkbox">';
                        $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes);
                        $answer_input .= $answer;
                        $answer_input .= '</label>';
                        if ($show_comment) {
                            $s .= '<tr><td>';
                            $s .= $answer_input;
                            $s .= '</td>';
                            $s .= '<td>';
                            $s .= $comment;
                            $s .= '</td>';
                            $s .= '</tr>';
                        } else {
                            $s .= $answer_input;
                        }
                    } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                        $my_choice = array();
                        if (!empty($user_choice_array)) {
                            foreach ($user_choice_array as $item) {
                                $item = explode(':', $item);
                                $my_choice[$item[0]] = $item[1];
                            }
                        }
                        $s .= '<tr>';
                        $s .= Display::tag('td', $answer);
                        if (!empty($quiz_question_options)) {
                            foreach ($quiz_question_options as $id => $item) {
                                if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) {
                                    $attributes = array('checked' => 1, 'selected' => 1);
                                } else {
                                    $attributes = array();
                                }
                                if ($debug_mark_answer) {
                                    if ($id == $answerCorrect) {
                                        $attributes['checked'] = 1;
                                        $attributes['selected'] = 1;
                                    }
                                }
                                $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => ''));
                            }
                        }
                        if ($show_comment) {
                            $s .= '<td>';
                            $s .= $comment;
                            $s .= '</td>';
                        }
                        $s .= '</tr>';
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
                    // multiple answers
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    if (in_array($numAnswer, $user_choice_array)) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    $answer = Security::remove_XSS($answer, STUDENT);
                    $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $answer_input .= '<label class="checkbox">';
                    $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($show_comment) {
                        $s .= '<tr>';
                        $s .= '<td>';
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                    $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $my_choice = array();
                    if (!empty($user_choice_array)) {
                        foreach ($user_choice_array as $item) {
                            $item = explode(':', $item);
                            if (isset($item[1]) && isset($item[0])) {
                                $my_choice[$item[0]] = $item[1];
                            }
                        }
                    }
                    $answer = Security::remove_XSS($answer, STUDENT);
                    $s .= '<tr>';
                    $s .= Display::tag('td', $answer);
                    foreach ($objQuestionTmp->options as $key => $item) {
                        if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) {
                            $attributes = array('checked' => 1, 'selected' => 1);
                        } else {
                            $attributes = array();
                        }
                        if ($debug_mark_answer) {
                            if ($key == $answerCorrect) {
                                $attributes['checked'] = 1;
                                $attributes['selected'] = 1;
                            }
                        }
                        $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes));
                    }
                    if ($show_comment) {
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                    }
                    $s .= '</tr>';
                } elseif ($answerType == FILL_IN_BLANKS) {
                    // display the question, with field empty, for student to fill it,
                    // or filled to display the answer in the Question preview of the exercice/admin.php page
                    $displayForStudent = true;
                    $listAnswerInformations = FillBlanks::getAnswerInfo($answer);
                    $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']);
                    $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']);
                    list($answer) = explode('::', $answer);
                    //Correct answers
                    $correctAnswerList = $listAnswerInformations['tabwords'];
                    //Student's answer
                    $studentAnswerList = array();
                    if (isset($user_choice[0]['answer'])) {
                        $arrayStudentAnswer = FillBlanks::getAnswerInfo($user_choice[0]['answer'], true);
                        $studentAnswerList = $arrayStudentAnswer['studentanswer'];
                    }
                    // If the question must be shown with the answer (in page exercice/admin.php) for teacher preview
                    // set the student-answer to the correct answer
                    if ($debug_mark_answer) {
                        $studentAnswerList = $correctAnswerList;
                        $displayForStudent = false;
                    }
                    if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
                        $answer = "";
                        for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) {
                            // display the common word
                            $answer .= $listAnswerInformations["commonwords"][$i];
                            // display the blank word
                            $correctItem = $listAnswerInformations["tabwords"][$i];
                            $correctItemRegexp = $correctItem;
                            // replace / with \/ to allow the preg_replace bellow and all the regexp char
                            $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp);
                            if (isset($studentAnswerList[$i])) {
                                // If student already started this test and answered this question,
                                // fill the blank with his previous answers
                                // may be "" if student viewed the question, but did not fill the blanks
                                $correctItem = $studentAnswerList[$i];
                            }
                            $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px";
                            $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, $correctItem, $attributes, $answer, $listAnswerInformations, $displayForStudent, $i);
                        }
                        // display the last common word
                        $answer .= $listAnswerInformations["commonwords"][$i];
                    } else {
                        // display empty [input] with the right width for student to fill it
                        $separatorStartRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorstart']);
                        $separatorEndRegexp = FillBlanks::escapeForRegexp($listAnswerInformations['blankseparatorend']);
                        $answer = "";
                        for ($i = 0; $i < count($listAnswerInformations["commonwords"]) - 1; $i++) {
                            // display the common words
                            $answer .= $listAnswerInformations["commonwords"][$i];
                            // display the blank word
                            $attributes["style"] = "width:" . $listAnswerInformations["tabinputsize"][$i] . "px";
                            $correctItem = $listAnswerInformations["tabwords"][$i];
                            $correctItemRegexp = $correctItem;
                            // replace / with \/ to allow the preg_replace bellow and all the regexp char
                            $correctItemRegexp = FillBlanks::getRegexpProtected($correctItemRegexp);
                            $answer .= FillBlanks::getFillTheBlankHtml($separatorStartRegexp, $separatorEndRegexp, $correctItemRegexp, $questionId, '', $attributes, $answer, $listAnswerInformations, $displayForStudent, $i);
                        }
                        // display the last common word
                        $answer .= $listAnswerInformations["commonwords"][$i];
                    }
                    $s .= $answer;
                } elseif ($answerType == CALCULATED_ANSWER) {
                    /*
                     * In the CALCULATED_ANSWER test
                     * you mustn't have [ and ] in the textarea
                     * you mustn't have @@ in the textarea
                     * the text to find mustn't be empty or contains only spaces
                     * the text to find mustn't contains HTML tags
                     * the text to find mustn't contains char "
                     */
                    if ($origin !== null) {
                        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;
                        $rsLastAttempt = Database::query($sql);
                        $rowLastAttempt = Database::fetch_array($rsLastAttempt);
                        $answer = $rowLastAttempt['answer'];
                        if (empty($answer)) {
                            $calculatedAnswerId = [];
                            $calculatedAnswerId[$questionId] = mt_rand(1, $nbrAnswers);
                            $answer = $objAnswerTmp->selectAnswer($calculatedAnswerId[$questionId]);
                            Session::write('calculatedAnswerId', $calculatedAnswerId);
                        }
                    }
                    list($answer) = explode('@@', $answer);
                    // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]]
                    api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList);
                    // 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('/\\[[^]]+\\]/', $answer, $studentAnswerList);
                        $studentAnswerListTobecleaned = $studentAnswerList[0];
                        $studentAnswerList = array();
                        for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) {
                            $answerCorrected = $studentAnswerListTobecleaned[$i];
                            $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected);
                            $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected);
                            $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected);
                            $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected);
                            $answerCorrected = '[' . $answerCorrected . ']';
                            $studentAnswerList[] = $answerCorrected;
                        }
                    }
                    // 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];
                    }
                    /*
                    Split the response by bracket
                    tabComments is an array with text surrounding the text to find
                    we add a space before and after the answerQuestion to be sure to
                    have a block of text before and after [xxx] patterns
                    so we have n text to find ([xxx]) and n+1 block of texts before,
                    between and after the text to find
                    */
                    $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' ');
                    if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
                        $answer = "";
                        $i = 0;
                        foreach ($studentAnswerList as $studentItem) {
                            // remove surronding brackets
                            $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2);
                            $size = strlen($studentItem);
                            $attributes['class'] = self::detectInputAppropriateClass($size);
                            $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes);
                            $i++;
                        }
                        $answer .= $tabComments[$i];
                    } else {
                        // display exercise with empty input fields
                        // every [xxx] are replaced with an empty input field
                        foreach ($correctAnswerList[0] as $item) {
                            $size = strlen($item);
                            $attributes['class'] = self::detectInputAppropriateClass($size);
                            $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer);
                        }
                    }
                    if ($origin !== null) {
                        $s = $answer;
                        break;
                    } else {
                        $s .= $answer;
                    }
                } elseif ($answerType == MATCHING) {
                    // matching type, showing suggestions and answers
                    // TODO: replace $answerId by $numAnswer
                    if ($answerCorrect != 0) {
                        // only show elements to be answered (not the contents of
                        // the select boxes, who are corrrect = 0)
                        $s .= '<tr><td width="45%" valign="top">';
                        $parsed_answer = $answer;
                        //left part questions
                        $s .= '<p class="indent">' . $lines_count . '.&nbsp;' . $parsed_answer . '</p></td>';
                        //middle part (matches selects)
                        $s .= '<td width="10%" valign="top" align="center" >
                                <div class="select-matching">
                                <select name="choice[' . $questionId . '][' . $numAnswer . ']">';
                        // fills the list-box
                        foreach ($select_items as $key => $val) {
                            // set $debug_mark_answer to true at function start to
                            // show the correct answer with a suffix '-x'
                            $selected = '';
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selected = 'selected="selected"';
                                }
                            }
                            //$user_choice_array_position
                            if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) {
                                $selected = 'selected="selected"';
                            }
                            $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>';
                        }
                        // end foreach()
                        $s .= '</select></div></td><td width="5%" class="separate">&nbsp;</td>';
                        $s .= '<td width="40%" valign="top" >';
                        if (isset($select_items[$lines_count])) {
                            $s .= '<div class="text-right"><p class="indent">' . $select_items[$lines_count]['letter'] . '.&nbsp; ' . $select_items[$lines_count]['answer'] . '</p></div>';
                        } else {
                            $s .= '&nbsp;';
                        }
                        $s .= '</td>';
                        $s .= '</tr>';
                        $lines_count++;
                        //if the left side of the "matching" has been completely
                        // shown but the right side still has values to show...
                        if ($lines_count - 1 == $num_suggestions) {
                            // if it remains answers to shown at the right side
                            while (isset($select_items[$lines_count])) {
                                $s .= '<tr>
                                      <td colspan="2"></td>
                                      <td valign="top">';
                                $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'];
                                $s .= "</td>\n                                </tr>";
                                $lines_count++;
                            }
                            // end while()
                        }
                        // end if()
                        $matching_correct_answer++;
                    }
                } elseif ($answerType == DRAGGABLE) {
                    if ($answerCorrect != 0) {
                        $parsed_answer = $answer;
                        /*$lines_count = '';
                          $data = $objAnswerTmp->getAnswerByAutoId($numAnswer);
                          $data = $objAnswerTmp->getAnswerByAutoId($data['correct']);
                          $lines_count = $data['answer'];*/
                        $windowId = $questionId . '_' . $lines_count;
                        $s .= '<li class="touch-items" id="' . $windowId . '">';
                        $s .= Display::div($parsed_answer, ['id' => "window_{$windowId}", 'class' => "window{$questionId}_question_draggable exercise-draggable-answer-option"]);
                        $selectedValue = 0;
                        $draggableSelectOptions = [];
                        foreach ($select_items as $key => $val) {
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selectedValue = $val['id'];
                                }
                            }
                            if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
                                $selectedValue = $val['id'];
                            }
                            $draggableSelectOptions[$val['id']] = $val['letter'];
                        }
                        $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $draggableSelectOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'select_option', 'style' => 'display: none;'], false);
                        if (!empty($answerCorrect) && !empty($selectedValue)) {
                            $s .= <<<JAVASCRIPT
                                <script>
                                    \$(function() {
                                        DraggableAnswer.deleteItem(
                                            \$('#{$questionId}_{$selectedValue}'),
                                            \$('#drop_{$windowId}')
                                        );
                                    });
                                </script>
JAVASCRIPT;
                        }
                        if (isset($select_items[$lines_count])) {
                            $s .= Display::div(Display::tag('b', $select_items[$lines_count]['letter']) . $select_items[$lines_count]['answer'], ['id' => "window_{$windowId}_answer", 'style' => 'display: none;']);
                        } else {
                            $s .= '&nbsp;';
                        }
                        $lines_count++;
                        if ($lines_count - 1 == $num_suggestions) {
                            while (isset($select_items[$lines_count])) {
                                $s .= Display::tag('b', $select_items[$lines_count]['letter']);
                                $s .= $select_items[$lines_count]['answer'];
                                $lines_count++;
                            }
                        }
                        $matching_correct_answer++;
                        $s .= '</li>';
                    }
                } elseif ($answerType == MATCHING_DRAGGABLE) {
                    if ($answerId == 1) {
                        echo $objAnswerTmp->getJs();
                    }
                    if ($answerCorrect != 0) {
                        $parsed_answer = $answer;
                        $windowId = "{$questionId}_{$lines_count}";
                        $s .= <<<HTML
                            <tr>
                                <td widht="45%">
                                    <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question">
                                        <strong>{$lines_count}.</strong> {$parsed_answer}
                                    </div>
                                </td>
                                <td width="10%">
HTML;
                        $selectedValue = 0;
                        $selectedPosition = 0;
                        $questionOptions = [];
                        $iTempt = 0;
                        foreach ($select_items as $key => $val) {
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selectedValue = $val['id'];
                                    $selectedPosition = $iTempt;
                                }
                            }
                            if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
                                $selectedValue = $val['id'];
                                $selectedPosition = $iTempt;
                            }
                            $questionOptions[$val['id']] = $val['letter'];
                            $iTempt++;
                        }
                        $s .= Display::select("choice[{$questionId}][{$numAnswer}]", $questionOptions, $selectedValue, ['id' => "window_{$windowId}_select", 'class' => 'hidden'], false);
                        if (!empty($answerCorrect) && !empty($selectedValue)) {
                            // Show connect if is not freeze (question preview)
                            if (!$freeze) {
                                $s .= <<<JAVASCRIPT
                                <script>
                                    \$(document).on('ready', function () {
                                        jsPlumb.ready(function() {
                                            jsPlumb.connect({
                                                source: 'window_{$windowId}',
                                                target: 'window_{$questionId}_{$selectedPosition}_answer',
                                                endpoint: ['Blank', {radius: 15}],
                                                anchors: ['RightMiddle', 'LeftMiddle'],
                                                paintStyle: {strokeStyle: '#8A8888', lineWidth: 8},
                                                connector: [
                                                    MatchingDraggable.connectorType,
                                                    {curvines: MatchingDraggable.curviness}
                                                ]
                                            });
                                        });
                                    });
                                </script>
JAVASCRIPT;
                            }
                        }
                        $s .= <<<HTML
                            </td>
                            <td width="45%">
HTML;
                        if (isset($select_items[$lines_count])) {
                            $s .= <<<HTML
                                <div id="window_{$windowId}_answer" class="window window_right_question">
                                    <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']}
                                </div>
HTML;
                        } else {
                            $s .= '&nbsp;';
                        }
                        $s .= '</td></tr>';
                        $lines_count++;
                        if ($lines_count - 1 == $num_suggestions) {
                            while (isset($select_items[$lines_count])) {
                                $s .= <<<HTML
                                    <tr>
                                        <td colspan="2"></td>
                                        <td>
                                            <strong>{$select_items[$lines_count]['letter']}</strong>
                                            {$select_items[$lines_count]['answer']}
                                        </td>
                                    </tr>
HTML;
                                $lines_count++;
                            }
                        }
                        $matching_correct_answer++;
                    }
                }
            }
            // end for()
            if ($show_comment) {
                $s .= '</table>';
            } elseif (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE, UNIQUE_ANSWER_NO_OPTION, MULTIPLE_ANSWER_TRUE_FALSE, MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE])) {
                $s .= '</table>';
            }
            if ($answerType == DRAGGABLE) {
                $s .= "</ul>";
                $s .= "</div>";
                //clearfix
                $counterAnswer = 1;
                $s .= '<div class="col-md-12"><div class="row">';
                for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                    $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                    $windowId = $questionId . '_' . $counterAnswer;
                    if ($answerCorrect) {
                        $s .= Display::div($counterAnswer, ['id' => "drop_{$windowId}", 'class' => 'droppable col-md-2']);
                        $counterAnswer++;
                    }
                }
                $s .= '</div>';
                // row
                $s .= '</div>';
                // col-md-12
                $s .= '</div>';
                // col-md-12 ui-widget ui-helper-clearfix
            }
            if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                $s .= '</div>';
                //drag_question
            }
            $s .= '</div>';
            //question_options row
            // destruction of the Answer object
            unset($objAnswerTmp);
            // destruction of the Question object
            unset($objQuestionTmp);
            if ($origin != 'export') {
                echo $s;
            } else {
                return $s;
            }
        } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
            global $exerciseId, $exe_id;
            // Question is a HOT_SPOT
            //checking document/images visibility
            if (api_is_platform_admin() || api_is_course_admin()) {
                $course = api_get_course_info();
                $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName);
                if (is_numeric($doc_id)) {
                    $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id());
                    if (!$images_folder_visibility) {
                        //This message is shown only to the course/platform admin if the image is set to visibility = false
                        Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage'));
                    }
                }
            }
            $questionName = $objQuestionTmp->selectTitle();
            $questionDescription = $objQuestionTmp->selectDescription();
            if ($freeze) {
                echo "\n                    <script>\n                        \$(document).on('ready', function () {\n                            new " . ($answerType == HOT_SPOT ? "HotspotQuestion" : "DelineationQuestion") . "({\n                                questionId: {$questionId},\n                                exerciseId: {$exerciseId},\n                                selector: '#hotspot-preview-{$questionId}',\n                                for: 'preview'\n                            });\n                        });\n                    </script>\n                    <div id=\"hotspot-preview-{$questionId}\"></div>\n                ";
                return;
            }
            // Get the answers, make a list
            $objAnswerTmp = new Answer($questionId);
            $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
            // get answers of hotpost
            $answers_hotspot = array();
            for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId));
                $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId);
            }
            $answerList = '';
            if ($answerType != HOT_SPOT_DELINEATION) {
                $answerList = '
                    <div class="well well-sm">
                        <h5 class="page-header">' . get_lang('HotspotZones') . '</h5>
                        <ol>
                ';
                if (!empty($answers_hotspot)) {
                    ksort($answers_hotspot);
                    $countAnswers = 1;
                    foreach ($answers_hotspot as $value) {
                        $answerList .= "<li><p>{$countAnswers} - {$value}</p></li>";
                        $countAnswers++;
                    }
                }
                $answerList .= '
                        </ol>
                    </div>
                ';
            }
            if (!$only_questions) {
                if ($show_title) {
                    TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
                    echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>';
                }
                //@todo I need to the get the feedback type
                echo <<<HOTSPOT
                    <input type="hidden" name="hidden_hotspot_id" value="{$questionId}" />
                    <div class="exercise_questions">
                        {$questionDescription}
                        <div class="row">
HOTSPOT;
            }
            $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
            $s .= "\n                            <div class=\"col-sm-8 col-md-9\">\n                                <div class=\"hotspot-image\"></div>\n                                <script>\n                                    \$(document).on('ready', function () {\n                                        new " . ($answerType == HOT_SPOT_DELINEATION ? 'DelineationQuestion' : 'HotspotQuestion') . "({\n                                            questionId: {$questionId},\n                                            exerciseId: {$exe_id},\n                                            selector: '#question_div_' + {$questionId} + ' .hotspot-image',\n                                            for: 'user'\n                                        });\n                                    });\n                                </script>\n                            </div>\n                            <div class=\"col-sm-4 col-md-3\">\n                                {$answerList}\n                            </div>\n            ";
            echo <<<HOTSPOT
                            {$s}
                        </div>
                    </div>
HOTSPOT;
        }
        return $nbrAnswers;
    }
Exemplo n.º 5
0
 /**
  * Duplicates answers by copying them into another question
  *
  * @author Olivier Brouckaert
  * @param  int question id
  * @param  array destination course info (result of the function api_get_course_info() )
  */
 public function duplicate($newQuestionId, $course_info = null)
 {
     if (empty($course_info)) {
         $course_info = $this->course;
     }
     $TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
     $fixed_list = array();
     if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE || self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE) {
         // Selecting origin options
         $origin_options = Question::readQuestionOption($this->selectQuestionId(), $this->course['real_id']);
         if (!empty($origin_options)) {
             foreach ($origin_options as $item) {
                 $new_option_list[] = $item['id'];
             }
         }
         $destination_options = Question::readQuestionOption($newQuestionId, $course_info['real_id']);
         $i = 0;
         if (!empty($destination_options)) {
             foreach ($destination_options as $item) {
                 $fixed_list[$new_option_list[$i]] = $item['id'];
                 $i++;
             }
         }
     }
     // if at least one answer
     if ($this->nbrAnswers) {
         // inserts new answers into data base
         $c_id = $course_info['real_id'];
         for ($i = 1; $i <= $this->nbrAnswers; $i++) {
             if ($this->course['id'] != $course_info['id']) {
                 $this->answer[$i] = DocumentManager::replace_urls_inside_content_html_from_copy_course($this->answer[$i], $this->course['id'], $course_info['id']);
                 $this->comment[$i] = DocumentManager::replace_urls_inside_content_html_from_copy_course($this->comment[$i], $this->course['id'], $course_info['id']);
             }
             $answer = $this->answer[$i];
             $correct = $this->correct[$i];
             if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE || self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE) {
                 $correct = $fixed_list[intval($correct)];
             }
             $comment = $this->comment[$i];
             $weighting = $this->weighting[$i];
             $position = $this->position[$i];
             $hotspot_coordinates = $this->hotspot_coordinates[$i];
             $hotspot_type = $this->hotspot_type[$i];
             $destination = $this->destination[$i];
             $params = ['c_id' => $c_id, 'question_id' => $newQuestionId, 'answer' => $answer, 'correct' => $correct, 'comment' => $comment, 'ponderation' => $weighting, 'position' => $position, 'hotspot_coordinates' => $hotspot_coordinates, 'hotspot_type' => $hotspot_type, 'destination' => $destination];
             $id = Database::insert($TBL_REPONSES, $params);
             if ($id) {
                 $sql = "UPDATE {$TBL_REPONSES} SET id = id_auto WHERE id_auto = {$id}";
                 Database::query($sql);
             }
         }
     }
 }
Exemplo n.º 6
0
/**
 * Shows a question
 *
 * @param int    $questionId question id
 * @param bool   $only_questions if true only show the questions, no exercise title
 * @param bool   $origin  i.e = learnpath
 * @param string $current_item current item from the list of questions
 * @param bool   $show_title
 * @param bool   $freeze
 * @param array  $user_choice
 * @param bool   $show_comment
 * @param bool   $exercise_feedback
 * @param bool   $show_answers
 * */
function showQuestion($questionId, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false)
{
    // Text direction for the current language
    $is_ltr_text_direction = api_get_text_direction() != 'rtl';
    // Change false to true in the following line to enable answer hinting
    $debug_mark_answer = $show_answers;
    //api_is_allowed_to_edit() && false;
    // Reads question information
    if (!($objQuestionTmp = Question::read($questionId))) {
        // Question not found
        return false;
    }
    if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) {
        $show_comment = false;
    }
    $answerType = $objQuestionTmp->selectType();
    $pictureName = $objQuestionTmp->selectPicture();
    $s = '';
    if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) {
        // Question is not a hotspot
        if (!$only_questions) {
            $questionDescription = $objQuestionTmp->selectDescription();
            if ($show_title) {
                Testcategory::displayCategoryAndTitle($objQuestionTmp->id);
                echo Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title'));
            }
            if (!empty($questionDescription)) {
                echo Display::div($questionDescription, array('class' => 'question_description'));
            }
        }
        if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) {
            return '';
        }
        echo '<div class="question_options">';
        // construction of the Answer object (also gets all answers details)
        $objAnswerTmp = new Answer($questionId);
        $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
        $course_id = api_get_course_int_id();
        $quiz_question_options = Question::readQuestionOption($questionId, $course_id);
        // For "matching" type here, we need something a little bit special
        // because the match between the suggestions and the answers cannot be
        // done easily (suggestions and answers are in the same table), so we
        // have to go through answers first (elems with "correct" value to 0).
        $select_items = array();
        //This will contain the number of answers on the left side. We call them
        // suggestions here, for the sake of comprehensions, while the ones
        // on the right side are called answers
        $num_suggestions = 0;
        if ($answerType == MATCHING) {
            $s .= '<table class="data_table">';
            // Iterate through answers
            $x = 1;
            //mark letters for each answer
            $letter = 'A';
            $answer_matching = array();
            $cpt1 = array();
            for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                $numAnswer = $objAnswerTmp->selectAutoId($answerId);
                $answer = $objAnswerTmp->selectAnswer($answerId);
                if ($answerCorrect == 0) {
                    // options (A, B, C, ...) that will be put into the list-box
                    // have the "correct" field set to 0 because they are answer
                    $cpt1[$x] = $letter;
                    $answer_matching[$x] = $objAnswerTmp->selectAnswerByAutoId($numAnswer);
                    $x++;
                    $letter++;
                }
            }
            $i = 1;
            $select_items[0]['id'] = 0;
            $select_items[0]['letter'] = '--';
            $select_items[0]['answer'] = '';
            foreach ($answer_matching as $id => $value) {
                $select_items[$i]['id'] = $value['id'];
                $select_items[$i]['letter'] = $cpt1[$id];
                $select_items[$i]['answer'] = $value['answer'];
                $i++;
            }
            $user_choice_array_position = array();
            if (!empty($user_choice)) {
                foreach ($user_choice as $item) {
                    $user_choice_array_position[$item['position']] = $item['answer'];
                }
            }
            $num_suggestions = $nbrAnswers - $x + 1;
        } elseif ($answerType == FREE_ANSWER) {
            $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null;
            $oFCKeditor = new FCKeditor("choice[" . $questionId . "]");
            $oFCKeditor->ToolbarSet = 'TestFreeAnswer';
            $oFCKeditor->Width = '100%';
            $oFCKeditor->Height = '200';
            $oFCKeditor->Value = $fck_content;
            $s .= $oFCKeditor->CreateHtml();
        } elseif ($answerType == ORAL_EXPRESSION) {
            //Add nanog
            if (api_get_setting('enable_nanogong') == 'true') {
                require_once api_get_path(LIBRARY_PATH) . 'nanogong.lib.php';
                //@todo pass this as a parameter
                global $exercise_stat_info, $exerciseId, $exe_id;
                if (!empty($exercise_stat_info)) {
                    $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId);
                } else {
                    $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId);
                }
                $nano = new Nanogong($params);
                echo $nano->show_button();
            }
            $oFCKeditor = new FCKeditor("choice[" . $questionId . "]");
            $oFCKeditor->ToolbarSet = 'TestFreeAnswer';
            $oFCKeditor->Width = '100%';
            $oFCKeditor->Height = '150';
            $oFCKeditor->ToolbarStartExpanded = false;
            $oFCKeditor->Value = '';
            $s .= $oFCKeditor->CreateHtml();
        }
        // Now navigate through the possible answers, using the max number of
        // answers for the question as a limiter
        $lines_count = 1;
        // a counter for matching-type answers
        if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
            $header = Display::tag('th', get_lang('Options'));
            foreach ($objQuestionTmp->options as $item) {
                if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                    if (in_array($item, $objQuestionTmp->options)) {
                        $header .= Display::tag('th', get_lang($item));
                    } else {
                        $header .= Display::tag('th', $item);
                    }
                } else {
                    $header .= Display::tag('th', $item);
                }
            }
            if ($show_comment) {
                $header .= Display::tag('th', get_lang('Feedback'));
            }
            $s .= '<table class="data_table">';
            $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
        }
        if ($show_comment) {
            if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) {
                $header = Display::tag('th', get_lang('Options'));
                if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) {
                    $header .= Display::tag('th', get_lang('Feedback'));
                }
                $s .= '<table class="data_table">';
                $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
            }
        }
        $matching_correct_answer = 0;
        $user_choice_array = array();
        if (!empty($user_choice)) {
            foreach ($user_choice as $item) {
                $user_choice_array[] = $item['answer'];
            }
        }
        for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
            $answer = $objAnswerTmp->selectAnswer($answerId);
            $answerCorrect = $objAnswerTmp->isCorrect($answerId);
            $numAnswer = $objAnswerTmp->selectAutoId($answerId);
            $comment = $objAnswerTmp->selectComment($answerId);
            $attributes = array();
            // Unique answer
            if ($answerType == UNIQUE_ANSWER || $answerType == UNIQUE_ANSWER_NO_OPTION) {
                $input_id = 'choice-' . $questionId . '-' . $answerId;
                if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
                    $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                } else {
                    $attributes = array('id' => $input_id);
                }
                if ($debug_mark_answer) {
                    if ($answerCorrect) {
                        $attributes['checked'] = 1;
                        $attributes['selected'] = 1;
                    }
                }
                $answer = Security::remove_XSS($answer, STUDENT);
                $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0');
                $answer_input = '<label class="radio">';
                $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes);
                $answer_input .= $answer;
                $answer_input .= '</label>';
                if ($show_comment) {
                    $s .= '<tr><td>';
                    $s .= $answer_input;
                    $s .= '</td>';
                    $s .= '<td>';
                    $s .= $comment;
                    $s .= '</td>';
                    $s .= '</tr>';
                } else {
                    $s .= $answer_input;
                }
            } elseif ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                $input_id = 'choice-' . $questionId . '-' . $answerId;
                $answer = Security::remove_XSS($answer, STUDENT);
                if (in_array($numAnswer, $user_choice_array)) {
                    $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                } else {
                    $attributes = array('id' => $input_id);
                }
                if ($debug_mark_answer) {
                    if ($answerCorrect) {
                        $attributes['checked'] = 1;
                        $attributes['selected'] = 1;
                    }
                }
                if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                    $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $answer_input = '<label class="checkbox">';
                    $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($show_comment) {
                        $s .= '<tr><td>';
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                    $my_choice = array();
                    if (!empty($user_choice_array)) {
                        foreach ($user_choice_array as $item) {
                            $item = explode(':', $item);
                            $my_choice[$item[0]] = $item[1];
                        }
                    }
                    $s .= '<tr>';
                    $s .= Display::tag('td', $answer);
                    if (!empty($quiz_question_options)) {
                        foreach ($quiz_question_options as $id => $item) {
                            if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) {
                                $attributes = array('checked' => 1, 'selected' => 1);
                            } else {
                                $attributes = array();
                            }
                            if ($debug_mark_answer) {
                                if ($id == $answerCorrect) {
                                    $attributes['checked'] = 1;
                                    $attributes['selected'] = 1;
                                }
                            }
                            $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => ''));
                        }
                    }
                    if ($show_comment) {
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                    }
                    $s .= '</tr>';
                }
            } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
                // multiple answers
                $input_id = 'choice-' . $questionId . '-' . $answerId;
                if (in_array($numAnswer, $user_choice_array)) {
                    $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                } else {
                    $attributes = array('id' => $input_id);
                }
                if ($debug_mark_answer) {
                    if ($answerCorrect) {
                        $attributes['checked'] = 1;
                        $attributes['selected'] = 1;
                    }
                }
                $answer = Security::remove_XSS($answer, STUDENT);
                $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                $answer_input .= '<label class="checkbox">';
                $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes);
                $answer_input .= $answer;
                $answer_input .= '</label>';
                if ($show_comment) {
                    $s .= '<tr>';
                    $s .= '<td>';
                    $s .= $answer_input;
                    $s .= '</td>';
                    $s .= '<td>';
                    $s .= $comment;
                    $s .= '</td>';
                    $s .= '</tr>';
                } else {
                    $s .= $answer_input;
                }
            } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                $my_choice = array();
                if (!empty($user_choice_array)) {
                    foreach ($user_choice_array as $item) {
                        $item = explode(':', $item);
                        $my_choice[$item[0]] = $item[1];
                    }
                }
                $answer = Security::remove_XSS($answer, STUDENT);
                $s .= '<tr>';
                $s .= Display::tag('td', $answer);
                foreach ($objQuestionTmp->options as $key => $item) {
                    if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) {
                        $attributes = array('checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array();
                    }
                    if ($debug_mark_answer) {
                        if ($key == $answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes));
                }
                if ($show_comment) {
                    $s .= '<td>';
                    $s .= $comment;
                    $s .= '</td>';
                }
                $s .= '</tr>';
            } elseif ($answerType == FILL_IN_BLANKS) {
                /*
                 * In the FILL_IN_BLANKS test
                 * you mustn't have [ and ] in the textarea
                 * you mustn't have :: in the textarea
                 * the text to find mustn't be empty or contains only spaces
                 * the text to find mustn't contains HTML tags
                 * the text to find mustn't contains char "
                 */
                list($answer) = explode('::', $answer);
                // $correct_answer_list array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]]
                api_preg_match_all('/\\[[^]]+\\]/', $answer, $correct_answer_list);
                // get student answer to display it if student go back to previous fillBlank answer question in a test
                if (isset($user_choice[0]['answer'])) {
                    api_preg_match_all('/\\[[^]]+\\]/', $user_choice[0]['answer'], $student_answer_list);
                    $student_answer_list_tobecleaned = $student_answer_list[0];
                    $student_answer_list = array();
                    // here we got the student answer in a test
                    // let's clean up the results
                    /*
                    Array
                    (
                        [0] => Array
                        (
                            [0] => [<font color="red"><s>yer</s></font> / <font color="green"><b>ici</b></font>]
                            [1] => [<font color="red"><s>plop</s></font> / <font color="green"><b>/p</b></font>]
                        )
                    )
                    */
                    for ($i = 0; $i < count($student_answer_list_tobecleaned); $i++) {
                        $answer_corrected = $student_answer_list_tobecleaned[$i];
                        /*
                         * we got if student answer is wrong
                         * [<font color="red"><s>rrr</s></font> / <font color="green"><b>/p</b></font>]
                         * or if student answer is good
                         * [plop / <font color="green"><b>plop</b></font>]
                         * or if student didn't answer []
                         */
                        $answer_corrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answer_corrected);
                        /*
                         * we got [<font color="red"><s>rrr</s></font> or [plop or [
                         */
                        $answer_corrected = api_preg_replace('/^\\[/', '', $answer_corrected);
                        /*
                         * we got <font color="red"><s>rrr</s></font> or plop
                         * non breakable spaces &nbsp;&nbsp;&nbsp; from /main/exercice/exercise.class.php have been removed l 2391 and l 2370
                         */
                        $answer_corrected = api_preg_replace('|^<font color="red"><s>|', '', $answer_corrected);
                        $answer_corrected = api_preg_replace('|</s></font>$|', '', $answer_corrected);
                        $answer_corrected = '[' . $answer_corrected . ']';
                        /*
                         * we got [rrr] or [plop] or []
                         */
                        $student_answer_list[] = $answer_corrected;
                    }
                }
                // 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
                    $student_answer_list = $correct_answer_list[0];
                }
                /*
                Split the response by bracket
                tab_comments is an array with text surrounding the text to find
                we add a space before and after the answer_question to be sure to
                have a block of text before and after [xxx] patterns
                so we have n text to find ([xxx]) and n+1 block of texts before,
                between and after the text to find
                */
                $tab_comments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' ');
                if (!empty($correct_answer_list) && !empty($student_answer_list)) {
                    $answer = "";
                    $i = 0;
                    foreach ($student_answer_list as $student_item) {
                        // remove surronding brackets
                        $student_response = api_substr($student_item, 1, api_strlen($student_item) - 2);
                        $size = strlen($student_item);
                        $attributes['class'] = detectInputAppropriateClass($size);
                        $answer .= $tab_comments[$i] . Display::input('text', "choice[{$questionId}][]", $student_response, $attributes);
                        $i++;
                    }
                    $answer .= $tab_comments[$i];
                } else {
                    // display exercise with empty input fields
                    // every [xxx] are replaced with an empty input field
                    foreach ($correct_answer_list[0] as $item) {
                        $size = strlen($item);
                        $attributes['class'] = detectInputAppropriateClass($size);
                        $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer);
                    }
                    /*$answer = api_preg_replace(
                      '/\[[^]]+\]/',
                      Display::input(
                          'text',
                          "choice[$questionId][]",
                          '',
                          $attributes
                      ), $answer);*/
                }
                $s .= $answer;
            } elseif ($answerType == CALCULATED_ANSWER) {
                /*
                 * In the CALCULATED_ANSWER test
                 * you mustn't have [ and ] in the textarea
                 * you mustn't have @@ in the textarea
                 * the text to find mustn't be empty or contains only spaces
                 * the text to find mustn't contains HTML tags
                 * the text to find mustn't contains char "
                 */
                if ($origin !== null) {
                    global $exe_id;
                    $trackAttempts = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
                    $sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId;
                    $rsLastAttempt = Database::query($sqlTrackAttempt);
                    $rowLastAttempt = Database::fetch_array($rsLastAttempt);
                    $answer = $rowLastAttempt['answer'];
                    if (empty($answer)) {
                        $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(1, $nbrAnswers);
                        $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
                    }
                }
                list($answer) = explode('@@', $answer);
                // $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]]
                api_preg_match_all('/\\[[^]]+\\]/', $answer, $correctAnswerList);
                // 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('/\\[[^]]+\\]/', $answer, $studentAnswerList);
                    $studentAnswerListTobecleaned = $studentAnswerList[0];
                    $studentAnswerList = array();
                    for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) {
                        $answerCorrected = $studentAnswerListTobecleaned[$i];
                        $answerCorrected = api_preg_replace('| / <font color="green"><b>.*$|', '', $answerCorrected);
                        $answerCorrected = api_preg_replace('/^\\[/', '', $answerCorrected);
                        $answerCorrected = api_preg_replace('|^<font color="red"><s>|', '', $answerCorrected);
                        $answerCorrected = api_preg_replace('|</s></font>$|', '', $answerCorrected);
                        $answerCorrected = '[' . $answerCorrected . ']';
                        $studentAnswerList[] = $answerCorrected;
                    }
                }
                // 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];
                }
                /*
                Split the response by bracket
                tabComments is an array with text surrounding the text to find
                we add a space before and after the answerQuestion to be sure to
                have a block of text before and after [xxx] patterns
                so we have n text to find ([xxx]) and n+1 block of texts before,
                between and after the text to find
                */
                $tabComments = api_preg_split('/\\[[^]]+\\]/', ' ' . $answer . ' ');
                if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
                    $answer = "";
                    $i = 0;
                    foreach ($studentAnswerList as $studentItem) {
                        // remove surronding brackets
                        $studentResponse = api_substr($studentItem, 1, api_strlen($studentItem) - 2);
                        $size = strlen($studentItem);
                        $attributes['class'] = detectInputAppropriateClass($size);
                        $answer .= $tabComments[$i] . Display::input('text', "choice[{$questionId}][]", $studentResponse, $attributes);
                        $i++;
                    }
                    $answer .= $tabComments[$i];
                } else {
                    // display exercise with empty input fields
                    // every [xxx] are replaced with an empty input field
                    foreach ($correctAnswerList[0] as $item) {
                        $size = strlen($item);
                        $attributes['class'] = detectInputAppropriateClass($size);
                        $answer = str_replace($item, Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer);
                    }
                }
                if ($origin !== null) {
                    $s = $answer;
                    break;
                } else {
                    $s .= $answer;
                }
            } elseif ($answerType == MATCHING) {
                // matching type, showing suggestions and answers
                // TODO: replace $answerId by $numAnswer
                if ($answerCorrect != 0) {
                    // only show elements to be answered (not the contents of
                    // the select boxes, who are corrrect = 0)
                    $s .= '<tr><td width="45%" valign="top">';
                    $parsed_answer = $answer;
                    //left part questions
                    $s .= ' <span style="float:left; width:8%;"><b>' . $lines_count . '</b>.&nbsp;</span>
    					 	<span style="float:left; width:92%;">' . $parsed_answer . '</span></td>';
                    //middle part (matches selects)
                    $s .= '<td width="10%" valign="top" align="center">&nbsp;&nbsp;
    			            <select name="choice[' . $questionId . '][' . $numAnswer . ']">';
                    // fills the list-box
                    foreach ($select_items as $key => $val) {
                        // set $debug_mark_answer to true at function start to
                        // show the correct answer with a suffix '-x'
                        $selected = '';
                        if ($debug_mark_answer) {
                            if ($val['id'] == $answerCorrect) {
                                $selected = 'selected="selected"';
                            }
                        }
                        //$user_choice_array_position
                        if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) {
                            $selected = 'selected="selected"';
                        }
                        /*if (isset($user_choice_array[$matching_correct_answer]) && $val['id'] == $user_choice_array[$matching_correct_answer]['answer']) {
                              $selected = 'selected="selected"';
                          }*/
                        $s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>';
                    }
                    // end foreach()
                    $s .= '</select></td>';
                    $s .= '<td width="45%" valign="top" >';
                    if (isset($select_items[$lines_count])) {
                        $s .= '<span style="float:left; width:5%;"><b>' . $select_items[$lines_count]['letter'] . '.</b></span>' . '<span style="float:left; width:95%;">' . $select_items[$lines_count]['answer'] . '</span>';
                    } else {
                        $s .= '&nbsp;';
                    }
                    $s .= '</td>';
                    $s .= '</tr>';
                    $lines_count++;
                    //if the left side of the "matching" has been completely
                    // shown but the right side still has values to show...
                    if ($lines_count - 1 == $num_suggestions) {
                        // if it remains answers to shown at the right side
                        while (isset($select_items[$lines_count])) {
                            $s .= '<tr>
    							  <td colspan="2"></td>
    							  <td valign="top">';
                            $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'];
                            $s .= "</td>\n    \t\t\t\t\t\t</tr>";
                            $lines_count++;
                        }
                        // end while()
                    }
                    // end if()
                    $matching_correct_answer++;
                }
            }
        }
        // end for()
        if ($show_comment) {
            $s .= '</table>';
        } else {
            if ($answerType == MATCHING || $answerType == UNIQUE_ANSWER_NO_OPTION || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                $s .= '</table>';
            }
        }
        $s .= '</div>';
        // destruction of the Answer object
        unset($objAnswerTmp);
        // destruction of the Question object
        unset($objQuestionTmp);
        if ($origin != 'export') {
            echo $s;
        } else {
            return $s;
        }
    } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
        // Question is a HOT_SPOT
        //checking document/images visibility
        if (api_is_platform_admin() || api_is_course_admin()) {
            require_once api_get_path(LIBRARY_PATH) . 'document.lib.php';
            $course = api_get_course_info();
            $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName);
            if (is_numeric($doc_id)) {
                $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id());
                if (!$images_folder_visibility) {
                    //This message is shown only to the course/platform admin if the image is set to visibility = false
                    Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage'));
                }
            }
        }
        $questionName = $objQuestionTmp->selectTitle();
        $questionDescription = $objQuestionTmp->selectDescription();
        if ($freeze) {
            echo Display::img($objQuestionTmp->selectPicturePath());
            return;
        }
        // Get the answers, make a list
        $objAnswerTmp = new Answer($questionId);
        $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
        // get answers of hotpost
        $answers_hotspot = array();
        for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
            $answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId));
            $answers_hotspot[$answers['id']] = $objAnswerTmp->selectAnswer($answerId);
        }
        // display answers of hotpost order by id
        $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>';
        if (!empty($answers_hotspot)) {
            ksort($answers_hotspot);
            foreach ($answers_hotspot as $key => $value) {
                $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />';
            }
        }
        $answer_list .= '</dl></div>';
        if ($answerType == HOT_SPOT_DELINEATION) {
            $answer_list = '';
            $swf_file = 'hotspot_delineation_user';
            $swf_height = 405;
        } else {
            $swf_file = 'hotspot_user';
            $swf_height = 436;
        }
        if (!$only_questions) {
            if ($show_title) {
                Testcategory::displayCategoryAndTitle($objQuestionTmp->id);
                echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>';
            }
            //@todo I need to the get the feedback type
            echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />';
            echo '<table class="exercise_questions" >
    			  <tr>
    		  		<td valign="top" colspan="2">';
            echo $questionDescription;
            echo '</td></tr>';
        }
        $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
        $s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
    					<script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script>
    					<script type="text/javascript">
    					<!--
    					// Globals
    					// Major version of Flash required
    					var requiredMajorVersion = 7;
    					// Minor version of Flash required
    					var requiredMinorVersion = 0;
    					// Minor version of Flash required
    					var requiredRevision = 0;
    					// the version of javascript supported
    					var jsVersion = 1.0;
    					// -->
    					</script>
    					<script language="VBScript" type="text/vbscript">
    					<!-- // Visual basic helper required to detect Flash Player ActiveX control version information
    					Function VBGetSwfVer(i)
    					  on error resume next
    					  Dim swControl, swVersion
    					  swVersion = 0

    					  set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))
    					  if (IsObject(swControl)) then
    					    swVersion = swControl.GetVariable("$version")
    					  end if
    					  VBGetSwfVer = swVersion
    					End Function
    					// -->
    					</script>

    					<script language="JavaScript1.1" type="text/javascript">
    					<!-- // Detect Client Browser type
    					var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
    					var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
    					var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
    					jsVersion = 1.1;
    					// JavaScript helper required to detect Flash Player PlugIn version information
    					function JSGetSwfVer(i) {
    						// NS/Opera version >= 3 check for Flash plugin in plugin array
    						if (navigator.plugins != null && navigator.plugins.length > 0) {
    							if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
    								var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
    					      		var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
    								descArray = flashDescription.split(" ");
    								tempArrayMajor = descArray[2].split(".");
    								versionMajor = tempArrayMajor[0];
    								versionMinor = tempArrayMajor[1];
    								if ( descArray[3] != "" ) {
    									tempArrayMinor = descArray[3].split("r");
    								} else {
    									tempArrayMinor = descArray[4].split("r");
    								}
    					      		versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
    					            flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
    					      	} else {
    								flashVer = -1;
    							}
    						}
    						// MSN/WebTV 2.6 supports Flash 4
    						else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
    						// WebTV 2.5 supports Flash 3
    						else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
    						// older WebTV supports Flash 2
    						else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
    						// Can\'t detect in all other cases
    						else
    						{
    							flashVer = -1;
    						}
    						return flashVer;
    					}
    					// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available

    					function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
    					 	reqVer = parseFloat(reqMajorVer + "." + reqRevision);
    					   	// loop backwards through the versions until we find the newest version
    						for (i=25;i>0;i--) {
    							if (isIE && isWin && !isOpera) {
    								versionStr = VBGetSwfVer(i);
    							} else {
    								versionStr = JSGetSwfVer(i);
    							}
    							if (versionStr == -1 ) {
    								return false;
    							} else if (versionStr != 0) {
    								if(isIE && isWin && !isOpera) {
    									tempArray         = versionStr.split(" ");
    									tempString        = tempArray[1];
    									versionArray      = tempString .split(",");
    								} else {
    									versionArray      = versionStr.split(".");
    								}
    								versionMajor      = versionArray[0];
    								versionMinor      = versionArray[1];
    								versionRevision   = versionArray[2];

    								versionString     = versionMajor + "." + versionRevision;   // 7.0r24 == 7.24
    								versionNum        = parseFloat(versionString);
    					        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
    								if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
    									return true;
    								} else {
    									return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
    								}
    							}
    						}
    					}
    					// -->
    					</script>';
        $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520">
    				<script>
    					<!--
    					// Version check based upon the values entered above in "Globals"
    					var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);

    					// Check to see if the version meets the requirements for playback
    					if (hasReqestedVersion) {  // if we\'ve detected an acceptable version
    					    var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&amp;canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\'
    					    			+ \'<param name="wmode" value="transparent">\'
    									+ \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&amp;canClick:' . $canClick . '" />\'
    									+ \'<\\/object>\';
    					    document.write(oeTags);   // embed the Flash Content SWF when all tests are passed
    					} else {  // flash is too old or we can\'t detect the plugin
    						var alternateContent = "Error<br \\/>"
    							+ "Hotspots requires Macromedia Flash 7.<br \\/>"
    							+ "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>";
    						document.write(alternateContent);  // insert non-flash content
    					}
    					// -->
    				</script>
    				</td>
    				<td valign="top" align="left">' . $answer_list . '</td></tr>
    				</table>
    	</td></tr>';
        echo $s;
        echo '</table>';
    }
    return $nbrAnswers;
}
Exemplo n.º 7
0
    /**
     * Shows a question
     * @param Question $objQuestionTmp
     * @param bool $only_questions if true only show the questions, no exercise title
     * @param bool $origin origin i.e = learnpath
     * @param string $current_item current item from the list of questions
     * @param bool $show_title
     * @param bool $freeze
     * @param array $user_choice
     * @param bool $show_comment
     * @param null $exercise_feedback
     * @param bool $show_answers
     * @param null $modelType
     * @param bool $categoryMinusOne
     * @return bool|null|string
     */
    public function showQuestion(Question $objQuestionTmp, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false, $modelType = null, $categoryMinusOne = true)
    {
        // Text direction for the current language
        //$is_ltr_text_direction = api_get_text_direction() != 'rtl';
        // Change false to true in the following line to enable answer hinting
        $debug_mark_answer = $show_answers;
        //api_is_allowed_to_edit() && false;
        // Reads question information
        if (!$objQuestionTmp) {
            // Question not found
            return false;
        }
        $html = null;
        $questionId = $objQuestionTmp->id;
        if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) {
            $show_comment = false;
        }
        $answerType = $objQuestionTmp->selectType();
        $pictureName = $objQuestionTmp->selectPicture();
        $s = null;
        $form = new FormValidator('question');
        $renderer = $form->defaultRenderer();
        $form_template = '{content}';
        $renderer->setFormTemplate($form_template);
        if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) {
            // Question is not a hotspot
            if (!$only_questions) {
                $questionDescription = $objQuestionTmp->selectDescription();
                if ($show_title) {
                    $categoryName = TestCategory::getCategoryNamesForQuestion($objQuestionTmp->id, null, true, $categoryMinusOne);
                    $html .= $categoryName;
                    $html .= Display::div($current_item . '. ' . $objQuestionTmp->selectTitle(), array('class' => 'question_title'));
                    if (!empty($questionDescription)) {
                        $html .= Display::div($questionDescription, array('class' => 'question_description'));
                    }
                } else {
                    $html .= '<div class="media">';
                    $html .= '<div class="pull-left">';
                    $html .= '<div class="media-object">';
                    $html .= Display::div($current_item, array('class' => 'question_no_title'));
                    $html .= '</div>';
                    $html .= '</div>';
                    $html .= '<div class="media-body">';
                    if (!empty($questionDescription)) {
                        $html .= Display::div($questionDescription, array('class' => 'question_description'));
                    }
                    $html .= '</div>';
                    $html .= '</div>';
                }
            }
            if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) {
                return null;
            }
            $html .= '<div class="question_options">';
            // construction of the Answer object (also gets all answers details)
            $objAnswerTmp = new Answer($questionId, null, $this);
            $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
            $course_id = api_get_course_int_id();
            $quiz_question_options = Question::readQuestionOption($questionId, $course_id);
            // For "matching" type here, we need something a little bit special
            // because the match between the suggestions and the answers cannot be
            // done easily (suggestions and answers are in the same table), so we
            // have to go through answers first (elems with "correct" value to 0).
            $select_items = array();
            //This will contain the number of answers on the left side. We call them
            // suggestions here, for the sake of comprehensions, while the ones
            // on the right side are called answers
            $num_suggestions = 0;
            if ($answerType == MATCHING || $answerType == DRAGGABLE) {
                if ($answerType == DRAGGABLE) {
                    $s .= '<div class="ui-widget ui-helper-clearfix">
                            <ul class="drag_question ui-helper-reset ui-helper-clearfix">';
                } else {
                    $s .= '<div id="drag' . $questionId . '_question" class="drag_question">';
                    $s .= '<table class="data_table">';
                }
                $j = 1;
                //iterate through answers
                $letter = 'A';
                //mark letters for each answer
                $answer_matching = array();
                $capital_letter = array();
                //for ($answerId=1; $answerId <= $nbrAnswers; $answerId++) {
                foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
                    $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                    $answer = $objAnswerTmp->selectAnswer($answerId);
                    if ($answerCorrect == 0) {
                        // options (A, B, C, ...) that will be put into the list-box
                        // have the "correct" field set to 0 because they are answer
                        $capital_letter[$j] = $letter;
                        //$answer_matching[$j]=$objAnswerTmp->selectAnswerByAutoId($numAnswer);
                        $answer_matching[$j] = array('id' => $answerId, 'answer' => $answer);
                        $j++;
                        $letter++;
                    }
                }
                $i = 1;
                $select_items[0]['id'] = 0;
                $select_items[0]['letter'] = '--';
                $select_items[0]['answer'] = '';
                foreach ($answer_matching as $id => $value) {
                    $select_items[$i]['id'] = $value['id'];
                    $select_items[$i]['letter'] = $capital_letter[$id];
                    $select_items[$i]['answer'] = $value['answer'];
                    $i++;
                }
                $num_suggestions = $nbrAnswers - $j + 1;
            } elseif ($answerType == FREE_ANSWER) {
                $content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null;
                $toolBar = 'TestFreeAnswer';
                if ($modelType == EXERCISE_MODEL_TYPE_COMMITTEE) {
                    $toolBar = 'TestFreeAnswerStrict';
                }
                $form->addElement('html_editor', "choice[" . $questionId . "]", null, array('id' => "choice[" . $questionId . "]"), array('ToolbarSet' => $toolBar));
                $form->setDefaults(array("choice[" . $questionId . "]" => $content));
                $s .= $form->return_form();
            } elseif ($answerType == ORAL_EXPRESSION) {
                // Add nanogong
                if (api_get_setting('document.enable_nanogong') == 'true') {
                    //@todo pass this as a parameter
                    global $exercise_stat_info, $exerciseId;
                    if (!empty($exercise_stat_info)) {
                        $params = array('exercise_id' => $exercise_stat_info['exe_exo_id'], 'exe_id' => $exercise_stat_info['exe_id'], 'question_id' => $questionId);
                    } else {
                        $params = array('exercise_id' => $exerciseId, 'exe_id' => 'temp_exe', 'question_id' => $questionId);
                    }
                    $nano = new Nanogong($params);
                    $s .= $nano->show_button();
                }
                $form->addElement('html_editor', "choice[" . $questionId . "]", null, array('id' => "choice[" . $questionId . "]"), array('ToolbarSet' => 'TestFreeAnswer'));
                //$form->setDefaults(array("choice[".$questionId."]" => $content));
                $s .= $form->return_form();
            }
            // Now navigate through the possible answers, using the max number of
            // answers for the question as a limiter
            $lines_count = 1;
            // a counter for matching-type answers
            if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                $header = Display::tag('th', get_lang('Options'));
                foreach ($objQuestionTmp->options as $item) {
                    $header .= Display::tag('th', $item);
                }
                if ($show_comment) {
                    $header .= Display::tag('th', get_lang('Feedback'));
                }
                $s .= '<table class="data_table">';
                $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
            }
            if ($show_comment) {
                if (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_COMBINATION, UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION, GLOBAL_MULTIPLE_ANSWER))) {
                    $header = Display::tag('th', get_lang('Options'));
                    if ($exercise_feedback == EXERCISE_FEEDBACK_TYPE_END) {
                        $header .= Display::tag('th', get_lang('Feedback'));
                    }
                    $s .= '<table class="data_table">';
                    $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
                }
            }
            $matching_correct_answer = 0;
            $user_choice_array = array();
            if (!empty($user_choice)) {
                foreach ($user_choice as $item) {
                    $user_choice_array[] = $item['answer'];
                }
            }
            foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
                $answer = $objAnswerTmp->selectAnswer($answerId);
                $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                $comment = $objAnswerTmp->selectComment($answerId);
                //$numAnswer       = $objAnswerTmp->selectAutoId($answerId);
                $numAnswer = $answerId;
                $attributes = array();
                // Unique answer
                if (in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION))) {
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    if (isset($user_choice[0]['answer']) && $user_choice[0]['answer'] == $numAnswer) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    $answer = Security::remove_XSS($answer);
                    $s .= Display::input('hidden', 'choice2[' . $questionId . ']', '0');
                    $answer_input = null;
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        $attributes['style'] = 'display:none';
                        $answer_input .= '<div id="answer' . $questionId . $numAnswer . '" style="float:left" class="highlight_image_default highlight_image">';
                    }
                    $answer_input .= '<label class="radio">';
                    $answer_input .= Display::input('radio', 'choice[' . $questionId . ']', $numAnswer, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($answerType == UNIQUE_ANSWER_IMAGE) {
                        $answer_input .= "</div>";
                    }
                    if ($show_comment) {
                        $s .= '<tr><td>';
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif (in_array($answerType, array(MULTIPLE_ANSWER, MULTIPLE_ANSWER_TRUE_FALSE, GLOBAL_MULTIPLE_ANSWER))) {
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    $answer = Security::remove_XSS($answer);
                    if (in_array($numAnswer, $user_choice_array)) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    if ($answerType == MULTIPLE_ANSWER || $answerType == GLOBAL_MULTIPLE_ANSWER) {
                        $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                        $answer_input = '<label class="checkbox">';
                        $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', $numAnswer, $attributes);
                        $answer_input .= $answer;
                        $answer_input .= '</label>';
                        if ($show_comment) {
                            $s .= '<tr><td>';
                            $s .= $answer_input;
                            $s .= '</td>';
                            $s .= '<td>';
                            $s .= $comment;
                            $s .= '</td>';
                            $s .= '</tr>';
                        } else {
                            $s .= $answer_input;
                        }
                    } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
                        $my_choice = array();
                        if (!empty($user_choice_array)) {
                            foreach ($user_choice_array as $item) {
                                $item = explode(':', $item);
                                $my_choice[$item[0]] = $item[1];
                            }
                        }
                        $s .= '<tr>';
                        $s .= Display::tag('td', $answer);
                        if (!empty($quiz_question_options)) {
                            foreach ($quiz_question_options as $id => $item) {
                                $id = $item['iid'];
                                if (isset($my_choice[$numAnswer]) && $id == $my_choice[$numAnswer]) {
                                    $attributes = array('checked' => 1, 'selected' => 1);
                                } else {
                                    $attributes = array();
                                }
                                if ($debug_mark_answer) {
                                    if ($id == $answerCorrect) {
                                        $attributes['checked'] = 1;
                                        $attributes['selected'] = 1;
                                    }
                                }
                                $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $id, $attributes), array('style' => ''));
                            }
                        }
                        if ($show_comment) {
                            $s .= '<td>';
                            $s .= $comment;
                            $s .= '</td>';
                        }
                        $s .= '</tr>';
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION) {
                    // multiple answers
                    $input_id = 'choice-' . $questionId . '-' . $answerId;
                    if (in_array($numAnswer, $user_choice_array)) {
                        $attributes = array('id' => $input_id, 'checked' => 1, 'selected' => 1);
                    } else {
                        $attributes = array('id' => $input_id);
                    }
                    if ($debug_mark_answer) {
                        if ($answerCorrect) {
                            $attributes['checked'] = 1;
                            $attributes['selected'] = 1;
                        }
                    }
                    $answer = Security::remove_XSS($answer);
                    $answer_input = '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $answer_input .= '<label class="checkbox">';
                    $answer_input .= Display::input('checkbox', 'choice[' . $questionId . '][' . $numAnswer . ']', 1, $attributes);
                    $answer_input .= $answer;
                    $answer_input .= '</label>';
                    if ($show_comment) {
                        $s .= '<tr>';
                        $s .= '<td>';
                        $s .= $answer_input;
                        $s .= '</td>';
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                        $s .= '</tr>';
                    } else {
                        $s .= $answer_input;
                    }
                } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                    $s .= '<input type="hidden" name="choice2[' . $questionId . ']" value="0" />';
                    $my_choice = array();
                    if (!empty($user_choice_array)) {
                        foreach ($user_choice_array as $item) {
                            $item = explode(':', $item);
                            $my_choice[$item[0]] = $item[1];
                        }
                    }
                    $answer = Security::remove_XSS($answer);
                    $s .= '<tr>';
                    $s .= Display::tag('td', $answer);
                    foreach ($objQuestionTmp->options as $key => $item) {
                        if (isset($my_choice[$numAnswer]) && $key == $my_choice[$numAnswer]) {
                            $attributes = array('checked' => 1, 'selected' => 1);
                        } else {
                            $attributes = array();
                        }
                        if ($debug_mark_answer) {
                            if ($key == $answerCorrect) {
                                $attributes['checked'] = 1;
                                $attributes['selected'] = 1;
                            }
                        }
                        $s .= Display::tag('td', Display::input('radio', 'choice[' . $questionId . '][' . $numAnswer . ']', $key, $attributes));
                    }
                    if ($show_comment) {
                        $s .= '<td>';
                        $s .= $comment;
                        $s .= '</td>';
                    }
                    $s .= '</tr>';
                } elseif ($answerType == FILL_IN_BLANKS) {
                    list($answer) = explode('::', $answer);
                    //Correct answer
                    api_preg_match_all('/\\[[^]]+\\]/', $answer, $correct_answer_list);
                    //Student's answezr
                    if (isset($user_choice[0]['answer'])) {
                        api_preg_match_all('/\\[[^]]+\\]/', $user_choice[0]['answer'], $student_answer_list);
                        $student_answer_list = $student_answer_list[0];
                    }
                    //If debug
                    if ($debug_mark_answer) {
                        $student_answer_list = $correct_answer_list[0];
                    }
                    if (!empty($correct_answer_list) && !empty($student_answer_list)) {
                        $correct_answer_list = $correct_answer_list[0];
                        $i = 0;
                        foreach ($correct_answer_list as $correct_item) {
                            $value = null;
                            if (isset($student_answer_list[$i]) && !empty($student_answer_list[$i])) {
                                //Cleaning student answer list
                                $value = strip_tags($student_answer_list[$i]);
                                $value = api_substr($value, 1, api_strlen($value) - 2);
                                $value = explode('/', $value);
                                if (!empty($value[0])) {
                                    $value = str_replace('&nbsp;', '', trim($value[0]));
                                }
                                $correct_item = preg_quote($correct_item);
                                $correct_item = api_preg_replace('|/|', '\\/', $correct_item);
                                // to prevent error if there is a / in the text to find
                                $answer = api_preg_replace('/' . $correct_item . '/', Display::input('text', "choice[{$questionId}][]", $value), $answer, 1);
                            }
                            $i++;
                        }
                    } else {
                        $answer = api_preg_replace('/\\[[^]]+\\]/', Display::input('text', "choice[{$questionId}][]", '', $attributes), $answer);
                    }
                    $s .= $answer;
                } elseif ($answerType == MATCHING) {
                    // matching type, showing suggestions and answers
                    // TODO: replace $answerId by $numAnswer
                    if ($lines_count == 1) {
                        $s .= $objAnswerTmp->getJs();
                    }
                    if ($answerCorrect != 0) {
                        // only show elements to be answered (not the contents of
                        // the select boxes, who are correct = 0)
                        $s .= '<tr><td width="45%">';
                        $parsed_answer = $answer;
                        $windowId = $questionId . '_' . $lines_count;
                        //left part questions
                        $s .= ' <div id="window_' . $windowId . '" class="window window_left_question window' . $questionId . '_question">
                                    <b>' . $lines_count . '</b>.&nbsp' . $parsed_answer . '
                                </div>
                                </td>';
                        // middle part (matches selects)
                        $s .= '<td width="10%" align="center">&nbsp;&nbsp;';
                        $s .= '<div style="display:block">';
                        $s .= '<select id="window_' . $windowId . '_select" name="choice[' . $questionId . '][' . $numAnswer . ']">';
                        $selectedValue = 0;
                        // fills the list-box
                        $item = 0;
                        foreach ($select_items as $val) {
                            // set $debug_mark_answer to true at public static function start to
                            // show the correct answer with a suffix '-x'
                            $selected = '';
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selected = 'selected="selected"';
                                    $selectedValue = $val['id'];
                                }
                            }
                            if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
                                $selected = 'selected="selected"';
                                $selectedValue = $val['id'];
                            }
                            //$s .= '<option value="'.$val['id'].'" '.$selected.'>'.$val['letter'].'</option>';
                            $s .= '<option value="' . $item . '" ' . $selected . '>' . $val['letter'] . '</option>';
                            $item++;
                        }
                        if (!empty($answerCorrect) && !empty($selectedValue)) {
                            $s .= '<script>
                                jsPlumb.ready(function() {
                                    jsPlumb.connect({
                                        source: "window_' . $windowId . '",
                                        target: "window_' . $questionId . '_' . $selectedValue . '_answer",
                                        endpoint:["Blank", { radius:15 }],
                                        anchor:["RightMiddle","LeftMiddle"],
                                        paintStyle:{ strokeStyle:"#8a8888" , lineWidth:8 },
                                        connector: [connectorType, { curviness: curvinessValue } ],
                                    })
                                });
                                </script>';
                        }
                        $s .= '</select></div></td>';
                        $s .= '<td width="45%" valign="top" >';
                        if (isset($select_items[$lines_count])) {
                            $s .= '<div id="window_' . $windowId . '_answer" class="window window_right_question">
                                    <b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'] . '
                                  </div>';
                        } else {
                            $s .= '&nbsp;';
                        }
                        $s .= '</td>';
                        $s .= '</tr>';
                        $lines_count++;
                        //if the left side of the "matching" has been completely
                        // shown but the right side still has values to show...
                        if ($lines_count - 1 == $num_suggestions) {
                            // if it remains answers to shown at the right side
                            while (isset($select_items[$lines_count])) {
                                $s .= '<tr>
                                      <td colspan="2"></td>
                                      <td valign="top">';
                                $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b>';
                                $s .= $select_items[$lines_count]['answer'];
                                $s .= "</td>\n                                </tr>";
                                $lines_count++;
                            }
                            // end while()
                        }
                        // end if()
                        $matching_correct_answer++;
                    }
                } elseif ($answerType == DRAGGABLE) {
                    // matching type, showing suggestions and answers
                    // TODO: replace $answerId by $numAnswer
                    if ($answerCorrect != 0) {
                        // only show elements to be answered (not the contents of
                        // the select boxes, who are correct = 0)
                        $s .= '<td>';
                        $parsed_answer = $answer;
                        $windowId = $questionId . '_' . $numAnswer;
                        //67_293 - 67_294
                        //left part questions
                        $s .= '<li class="ui-state-default" id="' . $windowId . '">';
                        $s .= ' <div id="window_' . $windowId . '" class="window' . $questionId . '_question_draggable question_draggable">
                                   ' . $parsed_answer . '
                                </div>';
                        $s .= '<div style="display:none">';
                        $s .= '<select id="window_' . $windowId . '_select" name="choice[' . $questionId . '][' . $numAnswer . ']" class="select_option">';
                        $selectedValue = 0;
                        // fills the list-box
                        $item = 0;
                        foreach ($select_items as $val) {
                            // set $debug_mark_answer to true at function start to
                            // show the correct answer with a suffix '-x'
                            $selected = '';
                            if ($debug_mark_answer) {
                                if ($val['id'] == $answerCorrect) {
                                    $selected = 'selected="selected"';
                                    $selectedValue = $val['id'];
                                }
                            }
                            if (isset($user_choice[$matching_correct_answer]) && $val['id'] == $user_choice[$matching_correct_answer]['answer']) {
                                $selected = 'selected="selected"';
                                $selectedValue = $val['id'];
                            }
                            //$s .= '<option value="'.$val['id'].'" '.$selected.'>'.$val['letter'].'</option>';
                            $s .= '<option value="' . $item . '" ' . $selected . '>' . $val['letter'] . '</option>';
                            $item++;
                        }
                        $s .= '</select>';
                        if (!empty($answerCorrect) && !empty($selectedValue)) {
                            $s .= '<script>
                                $(function() {
                                    deleteItem($("#' . $questionId . '_' . $selectedValue . '"), $("#drop_' . $windowId . '"));
                                });
                                </script>';
                        }
                        if (isset($select_items[$lines_count])) {
                            $s .= '<div id="window_' . $windowId . '_answer" class="">
                                    <b>' . $select_items[$lines_count]['letter'] . '.</b> ' . $select_items[$lines_count]['answer'] . '
                                  </div>';
                        } else {
                            $s .= '&nbsp;';
                        }
                        $lines_count++;
                        //if the left side of the "matching" has been completely
                        // shown but the right side still has values to show...
                        if ($lines_count - 1 == $num_suggestions) {
                            // if it remains answers to shown at the right side
                            while (isset($select_items[$lines_count])) {
                                $s .= '<b>' . $select_items[$lines_count]['letter'] . '.</b>';
                                $s .= $select_items[$lines_count]['answer'];
                                $lines_count++;
                            }
                        }
                        $s .= '</div>';
                        $matching_correct_answer++;
                        $s .= '</li>';
                    }
                }
            }
            // end for()
            if ($show_comment) {
                $s .= '</table>';
            } else {
                if ($answerType == MATCHING || $answerType == UNIQUE_ANSWER_NO_OPTION || $answerType == MULTIPLE_ANSWER_TRUE_FALSE || $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
                    $s .= '</table>';
                }
            }
            if ($answerType == DRAGGABLE) {
                $s .= '</ul><div class="clear"></div>';
                $counterAnswer = 1;
                foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
                    $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                    $windowId = $questionId . '_' . $counterAnswer;
                    if ($answerCorrect == 0) {
                        $s .= '<div id="drop_' . $windowId . '" class="droppable ui-state-default">' . $counterAnswer . '</div>';
                        $counterAnswer++;
                    }
                }
            }
            if ($answerType == MATCHING) {
                $s .= '</div>';
            }
            $s .= '</div>';
            // destruction of the Answer object
            unset($objAnswerTmp);
            // destruction of the Question object
            unset($objQuestionTmp);
            $html .= $s;
            return $html;
        } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
            // Question is a HOT_SPOT
            //checking document/images visibility
            if (api_is_platform_admin() || api_is_course_admin()) {
                $course = api_get_course_info();
                $doc_id = DocumentManager::get_document_id($course, '/images/' . $pictureName);
                if (is_numeric($doc_id)) {
                    $images_folder_visibility = api_get_item_visibility($course, 'document', $doc_id, api_get_session_id());
                    if (!$images_folder_visibility) {
                        //This message is shown only to the course/platform admin if the image is set to visibility = false
                        Display::display_warning_message(get_lang('ChangeTheVisibilityOfTheCurrentImage'));
                    }
                }
            }
            $questionName = $objQuestionTmp->selectTitle();
            $questionDescription = $objQuestionTmp->selectDescription();
            if ($freeze) {
                $s .= Display::img($objQuestionTmp->selectPicturePath());
                $html .= $s;
                return $html;
            }
            // Get the answers, make a list
            $objAnswerTmp = new Answer($questionId);
            // get answers of hotpost
            $answers_hotspot = array();
            foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
                //$answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId));
                $answers_hotspot[$answerId] = $objAnswerTmp->selectAnswer($answerId);
            }
            // display answers of hotpost order by id
            $answer_list = '<div style="padding: 10px; margin-left: 0px; border: 1px solid #A4A4A4; height: 408px; width: 200px;"><b>' . get_lang('HotspotZones') . '</b><dl>';
            if (!empty($answers_hotspot)) {
                ksort($answers_hotspot);
                foreach ($answers_hotspot as $key => $value) {
                    $answer_list .= '<dt>' . $key . '.- ' . $value . '</dt><br />';
                }
            }
            $answer_list .= '</dl></div>';
            if ($answerType == HOT_SPOT_DELINEATION) {
                $answer_list = '';
                $swf_file = 'hotspot_delineation_user';
                $swf_height = 405;
            } else {
                $swf_file = 'hotspot_user';
                $swf_height = 436;
            }
            if (!$only_questions) {
                if ($show_title) {
                    $html .= TestCategory::getCategoryNamesForQuestion($objQuestionTmp->id);
                    $html .= '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>';
                    $html .= $questionDescription;
                } else {
                    $html .= '<div class="media">';
                    $html .= '<div class="pull-left">';
                    $html .= '<div class="media-object">';
                    $html .= Display::div($current_item . '. ', array('class' => 'question_no_title'));
                    $html .= '</div>';
                    $html .= '</div>';
                    $html .= '<div class="media-body">';
                    if (!empty($questionDescription)) {
                        $html .= Display::div($questionDescription, array('class' => 'question_description'));
                    }
                    $html .= '</div>';
                    $html .= '</div>';
                }
                //@todo I need to the get the feedback type
                $html .= '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />';
                $html .= '<table class="exercise_questions">
                           <tr>
                            <td valign="top" colspan="2">';
                $html .= '</td></tr>';
            }
            $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
            $s .= ' <script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
                    <script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script>
                    <script type="text/javascript">
                    <!--
                    // Globals
                    // Major version of Flash required
                    var requiredMajorVersion = 7;
                    // Minor version of Flash required
                    var requiredMinorVersion = 0;
                    // Minor version of Flash required
                    var requiredRevision = 0;
                    // the version of javascript supported
                    var jsVersion = 1.0;
                    // -->
                    </script>
                    <script language="VBScript" type="text/vbscript">
                    <!-- // Visual basic helper required to detect Flash Player ActiveX control version information
                    Function VBGetSwfVer(i)
                      on error resume next
                      Dim swControl, swVersion
                      swVersion = 0

                      set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))
                      if (IsObject(swControl)) then
                        swVersion = swControl.GetVariable("$version")
                      end if
                      VBGetSwfVer = swVersion
                    End Function
                    // -->
                    </script>

                    <script language="JavaScript1.1" type="text/javascript">
                    <!-- // Detect Client Browser type
                    var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
                    var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
                    var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
                    jsVersion = 1.1;
                    // JavaScript helper required to detect Flash Player PlugIn version information
                    function JSGetSwfVer(i) {
                        // NS/Opera version >= 3 check for Flash plugin in plugin array
                        if (navigator.plugins != null && navigator.plugins.length > 0) {
                            if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
                                var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
                                var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
                                descArray = flashDescription.split(" ");
                                tempArrayMajor = descArray[2].split(".");
                                versionMajor = tempArrayMajor[0];
                                versionMinor = tempArrayMajor[1];
                                if ( descArray[3] != "" ) {
                                    tempArrayMinor = descArray[3].split("r");
                                } else {
                                    tempArrayMinor = descArray[4].split("r");
                                }
                                versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
                                flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
                            } else {
                                flashVer = -1;
                            }
                        }
                        // MSN/WebTV 2.6 supports Flash 4
                        else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
                        // WebTV 2.5 supports Flash 3
                        else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
                        // older WebTV supports Flash 2
                        else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
                        // Can\'t detect in all other cases
                        else {
                            flashVer = -1;
                        }
                        return flashVer;
                    }
                    // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available

                    function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
                        reqVer = parseFloat(reqMajorVer + "." + reqRevision);
                        // loop backwards through the versions until we find the newest version
                        for (i=25;i>0;i--) {
                            if (isIE && isWin && !isOpera) {
                                versionStr = VBGetSwfVer(i);
                            } else {
                                versionStr = JSGetSwfVer(i);
                            }
                            if (versionStr == -1 ) {
                                return false;
                            } else if (versionStr != 0) {
                                if(isIE && isWin && !isOpera) {
                                    tempArray         = versionStr.split(" ");
                                    tempString        = tempArray[1];
                                    versionArray      = tempString .split(",");
                                } else {
                                    versionArray      = versionStr.split(".");
                                }
                                versionMajor      = versionArray[0];
                                versionMinor      = versionArray[1];
                                versionRevision   = versionArray[2];

                                versionString     = versionMajor + "." + versionRevision;   // 7.0r24 == 7.24
                                versionNum        = parseFloat(versionString);
                                // is the major.revision >= requested major.revision AND the minor version >= requested minor
                                if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
                                    return true;
                                } else {
                                    return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
                                }
                            }
                        }
                    }
                    // -->
                    </script>';
            $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520">
                    <script>
                        // Version check based upon the values entered above in "Globals"
                        var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);

                        // Check to see if the version meets the requirements for playback
                        if (hasReqestedVersion) {  // if we\'ve detected an acceptable version
                            var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&amp;canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\'
                                        + \'<param name="wmode" value="transparent">\'
                                        + \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&amp;canClick:' . $canClick . '" />\'
                                        + \'<\\/object>\';
                            document.write(oeTags);   // embed the Flash Content SWF when all tests are passed
                        } else {  // flash is too old or we can\'t detect the plugin
                            var alternateContent = "Error<br \\/>"
                                + "Hotspots requires Macromedia Flash 7.<br \\/>"
                                + "<a href=\\"http://www.macromedia.com/go/getflash/\\">Get Flash<\\/a>";
                            document.write(alternateContent);  // insert non-flash content
                        }
                    </script>
                    </td>
                    <td valign="top" align="left">' . $answer_list . '</td></tr>
                    </table>
            </td></tr>';
            $html .= $s;
            $html .= '</table>';
            return $html;
        }
        return $nbrAnswers;
    }
    /**
     * Display the answers to a multiple choice question
     *
     * @param integer Answer type
     * @param integer Student choice
     * @param string  Textual answer
     * @param string  Comment on answer
     * @param string  Correct answer comment
     * @param integer Exercise ID
     * @param integer Question ID
     * @param boolean Whether to show the answer comment or not
     * @return void
     */
    public static function display_multiple_answer_true_false($feedback_type, $answerType, $studentChoice, $answer, $answerComment, $answerCorrect, $id, $questionId, $ans, $in_results_disabled)
    {
        $hide_expected_answer = false;
        if ($feedback_type == 0 && $in_results_disabled == 2) {
            $hide_expected_answer = true;
        }
        ?>
        <tr>
        <td width="5%">
        <?php 
        $question = new MultipleAnswerTrueFalse();
        $course_id = api_get_course_int_id();
        $new_options = Question::readQuestionOption($questionId, $course_id);
        //Your choice
        if (isset($new_options[$studentChoice])) {
            echo get_lang($new_options[$studentChoice]['name']);
        } else {
            echo '-';
        }
        ?>
        </td>
        <td width="5%">
        <?php 
        //Expected choice
        if (!$hide_expected_answer) {
            if (isset($new_options[$answerCorrect])) {
                echo get_lang($new_options[$answerCorrect]['name']);
            } else {
                echo '-';
            }
        } else {
            echo '-';
        }
        ?>
        </td>
        <td width="40%">
			<?php 
        echo $answer;
        ?>
        </td>

        <?php 
        if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
            ?>
        <td width="20%">
            <?php 
            $color = "black";
            if (isset($new_options[$studentChoice])) {
                if ($studentChoice == $answerCorrect) {
                    $color = "green";
                }
                echo '<span style="font-weight: bold; color: ' . $color . ';">' . nl2br($answerComment) . '</span>';
            }
            ?>
        </td>
            <?php 
            if ($ans == 1) {
                $comm = Event::get_comments($id, $questionId);
            }
            ?>
         <?php 
        } else {
            ?>
            <td>&nbsp;</td>
        <?php 
        }
        ?>
        </tr>
        <?php 
    }
 /**
  * Restore quiz-questions
  * @params int question id
  */
 public function restore_quiz_question($id)
 {
     $resources = $this->course->resources;
     $question = isset($resources[RESOURCE_QUIZQUESTION][$id]) ? $resources[RESOURCE_QUIZQUESTION][$id] : null;
     $new_id = 0;
     if (is_object($question)) {
         if ($question->is_restored()) {
             return $question->destination_id;
         }
         $table_que = Database::get_course_table(TABLE_QUIZ_QUESTION);
         $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
         $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
         // check resources inside html from ckeditor tool and copy correct urls into recipient course
         $question->description = DocumentManager::replace_urls_inside_content_html_from_copy_course($question->description, $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
         $params = ['c_id' => $this->destination_course_id, 'question' => self::DBUTF8($question->question), 'description' => self::DBUTF8($question->description), 'ponderation' => self::DBUTF8($question->ponderation), 'position' => self::DBUTF8($question->position), 'type' => self::DBUTF8($question->quiz_type), 'picture' => self::DBUTF8($question->picture), 'level' => self::DBUTF8($question->level), 'extra' => self::DBUTF8($question->extra)];
         $new_id = Database::insert($table_que, $params);
         if ($new_id) {
             $sql = "UPDATE {$table_que} SET id = iid WHERE iid = {$new_id}";
             Database::query($sql);
             if (!empty($question->picture)) {
                 $question_temp = Question::read($new_id, $this->destination_course_info['real_id']);
                 $documentPath = api_get_path(SYS_COURSE_PATH) . $this->destination_course_info['path'] . '/document';
                 // picture path
                 $picturePath = $documentPath . '/images';
                 $old_picture = api_get_path(SYS_COURSE_PATH) . $this->course->info['path'] . '/document/images/' . $question->picture;
                 if (file_exists($old_picture)) {
                     $picture_name = 'quiz-' . $new_id . '.jpg';
                     $result = $question_temp->uploadPicture($old_picture, $picture_name, $picturePath);
                     if ($result) {
                         $sql = "UPDATE {$table_que} SET\n                                        picture = '{$picture_name}'\n                                    WHERE\n                                        c_id = " . $this->destination_course_id . " AND\n                                        id = {$new_id} ";
                         Database::query($sql);
                     }
                 }
             }
         }
         if (in_array($question->quiz_type, [MATCHING, MATCHING_DRAGGABLE])) {
             $temp = array();
             foreach ($question->answers as $index => $answer) {
                 $temp[$answer['position']] = $answer;
             }
             foreach ($temp as $index => $answer) {
                 //id = '".$index."',
                 $params = ['c_id' => $this->destination_course_id, 'question_id' => $new_id, 'answer' => self::DBUTF8($answer['answer']), 'correct' => $answer['correct'], 'comment' => self::DBUTF8($answer['comment']), 'ponderation' => $answer['ponderation'], 'position' => $answer['position'], 'hotspot_coordinates' => $answer['hotspot_coordinates'], 'hotspot_type' => $answer['hotspot_type']];
                 $answerId = Database::insert($table_ans, $params);
                 if ($answerId) {
                     $sql = "UPDATE {$table_ans} SET id = iid, id_auto = iid WHERE iid = {$answerId}";
                     Database::query($sql);
                 }
             }
         } else {
             $correct_answers = array();
             foreach ($question->answers as $index => $answer) {
                 // check resources inside html from ckeditor tool and copy correct urls into recipient course
                 $answer['answer'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($answer['answer'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
                 $answer['comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($answer['comment'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
                 //                     id = '". ($index + 1)."',
                 $params = ['c_id' => $this->destination_course_id, 'question_id' => $new_id, 'answer' => self::DBUTF8($answer['answer']), 'correct' => $answer['correct'], 'comment' => self::DBUTF8($answer['comment']), 'ponderation' => $answer['ponderation'], 'position' => $answer['position'], 'hotspot_coordinates' => $answer['hotspot_coordinates'], 'hotspot_type' => $answer['hotspot_type']];
                 $answerId = Database::insert($table_ans, $params);
                 if ($answerId) {
                     $sql = "UPDATE {$table_ans} SET id = iid, id_auto = iid WHERE iid = {$answerId}";
                     Database::query($sql);
                 }
                 $correct_answers[$answerId] = $answer['correct'];
             }
         }
         //Current course id
         $course_id = api_get_course_int_id();
         //Moving quiz_question_options
         if ($question->quiz_type == MULTIPLE_ANSWER_TRUE_FALSE) {
             $question_option_list = Question::readQuestionOption($id, $course_id);
             //Question copied from the current platform
             if ($question_option_list) {
                 $old_option_ids = array();
                 foreach ($question_option_list as $item) {
                     $old_id = $item['id'];
                     unset($item['id']);
                     if (isset($item['iid'])) {
                         unset($item['iid']);
                     }
                     $item['question_id'] = $new_id;
                     $item['c_id'] = $this->destination_course_id;
                     $question_option_id = Database::insert($table_options, $item);
                     if ($question_option_id) {
                         $old_option_ids[$old_id] = $question_option_id;
                         $sql = "UPDATE {$table_options} SET id = iid WHERE iid = {$question_option_id}";
                         Database::query($sql);
                     }
                 }
                 if ($old_option_ids) {
                     $new_answers = Database::select('iid, correct', $table_ans, array('WHERE' => array('question_id = ? AND c_id = ? ' => array($new_id, $this->destination_course_id))));
                     foreach ($new_answers as $answer_item) {
                         $params = array();
                         $params['correct'] = $old_option_ids[$answer_item['correct']];
                         Database::update($table_ans, $params, array('iid = ? AND c_id = ? AND question_id = ? ' => array($answer_item['iid'], $this->destination_course_id, $new_id)), false);
                     }
                 }
             } else {
                 $new_options = array();
                 if (isset($question->question_options)) {
                     foreach ($question->question_options as $obj) {
                         $item = array();
                         $item['question_id'] = $new_id;
                         $item['c_id'] = $this->destination_course_id;
                         $item['name'] = $obj->obj->name;
                         $item['position'] = $obj->obj->position;
                         $question_option_id = Database::insert($table_options, $item);
                         if ($question_option_id) {
                             $new_options[$obj->obj->id] = $question_option_id;
                             $sql = "UPDATE {$table_options} SET id = iid WHERE iid = {$question_option_id}";
                             Database::query($sql);
                         }
                     }
                     foreach ($correct_answers as $answer_id => $correct_answer) {
                         $params = array();
                         $params['correct'] = $new_options[$correct_answer];
                         Database::update($table_ans, $params, array('id = ? AND c_id = ? AND question_id = ? ' => array($answer_id, $this->destination_course_id, $new_id)), false);
                     }
                 }
             }
         }
         $this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
     }
     return $new_id;
 }
 /**
  * abstract function which creates the form to create / edit the answers of the question
  * @param FormValidator $form
  */
 public function processAnswersCreation($form)
 {
     $questionWeighting = $nbrGoodAnswers = 0;
     $objAnswer = new Answer($this->id);
     $nb_answers = $form->getSubmitValue('nb_answers');
     $options_count = $form->getSubmitValue('options_count');
     $course_id = api_get_course_int_id();
     $correct = array();
     $options = Question::readQuestionOption($this->id, $course_id);
     if (!empty($options)) {
         foreach ($options as $option_data) {
             $id = $option_data['id'];
             unset($option_data['id']);
             Question::updateQuestionOption($id, $option_data, $course_id);
         }
     } else {
         for ($i = 1; $i <= 3; $i++) {
             $last_id = Question::saveQuestionOption($this->id, $this->options[$i], $course_id, $i);
             $correct[$i] = $last_id;
         }
     }
     /* Getting quiz_question_options (true, false, doubt) because
        it's possible that there are more options in the future */
     $new_options = Question::readQuestionOption($this->id, $course_id);
     $sorted_by_position = array();
     foreach ($new_options as $item) {
         $sorted_by_position[$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.*/
     $extra_values = array();
     for ($i = 1; $i <= 3; $i++) {
         $score = trim($form->getSubmitValue('option[' . $i . ']'));
         $extra_values[] = $score;
     }
     $this->setExtra(implode(':', $extra_values));
     for ($i = 1; $i <= $nb_answers; $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 = $sorted_by_position[$goodAnswer]['id'];
         }
         $questionWeighting += $extra_values[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();
 }
Exemplo n.º 11
0
 /**
  * Duplicates answers by copying them into another question
  *
  * @author Olivier Brouckaert
  * @param  int question id
  * @param  array destination course info (result of the function api_get_course_info() )
  */
 public function duplicate($newQuestionId, $course_info = null)
 {
     if (empty($course_info)) {
         $course_info = $this->course;
     } else {
         $course_info = $course_info;
     }
     $TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
     if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE || self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE) {
         //Selecting origin options
         $origin_options = Question::readQuestionOption($this->selectQuestionId(), $this->course['real_id']);
         if (!empty($origin_options)) {
             foreach ($origin_options as $item) {
                 $new_option_list[] = $item['id'];
             }
         }
         $destination_options = Question::readQuestionOption($newQuestionId, $course_info['real_id']);
         $i = 0;
         $fixed_list = array();
         if (!empty($destination_options)) {
             foreach ($destination_options as $item) {
                 $fixed_list[$new_option_list[$i]] = $item['id'];
                 $i++;
             }
         }
     }
     // if at least one answer
     if ($this->nbrAnswers) {
         // inserts new answers into data base
         $c_id = $course_info['real_id'];
         $correct_answers = array();
         $new_ids = array();
         foreach ($this->answer as $answer_id => $answer_item) {
             $i = $answer_id;
             if ($this->course['id'] != $course_info['id']) {
                 $this->answer[$i] = DocumentManager::replace_urls_inside_content_html_from_copy_course($this->answer[$i], $this->course['id'], $course_info['id']);
                 $this->comment[$i] = DocumentManager::replace_urls_inside_content_html_from_copy_course($this->comment[$i], $this->course['id'], $course_info['id']);
             }
             $answer = Database::escape_string($this->answer[$i]);
             $correct = Database::escape_string($this->correct[$i]);
             if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE || self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE) {
                 $correct = $fixed_list[intval($correct)];
             }
             $comment = Database::escape_string($this->comment[$i]);
             $weighting = Database::escape_string($this->weighting[$i]);
             $position = Database::escape_string($this->position[$i]);
             $hotspot_coordinates = Database::escape_string($this->hotspot_coordinates[$i]);
             $hotspot_type = Database::escape_string($this->hotspot_type[$i]);
             $destination = Database::escape_string($this->destination[$i]);
             $sql = "INSERT INTO {$TBL_REPONSES}(question_id, answer, correct, comment, ponderation, position, hotspot_coordinates, hotspot_type ,destination) VALUES";
             $sql .= "('{$newQuestionId}','{$answer}','{$correct}','{$comment}', '{$weighting}','{$position}','{$hotspot_coordinates}','{$hotspot_type}','{$destination}')";
             Database::query($sql);
             $new_id = Database::insert_id();
             $new_ids[$answer_id] = $new_id;
             if ($correct) {
                 $correct_answers[$new_id] = $correct;
             }
         }
         if (self::getQuestionType() == MATCHING) {
             if (!empty($correct_answers)) {
                 foreach ($correct_answers as $new_id => $correct_id) {
                     $correct = $new_ids[$correct_id];
                     $sql = "UPDATE {$TBL_REPONSES} SET correct = {$correct} WHERE iid = {$new_id}";
                     Database::query($sql);
                 }
             }
         }
     }
 }