Browse Source

Fix format from 1.9.x to 1.10 see BT#10434

Julio 9 years ago
parent
commit
461a8de436
2 changed files with 237 additions and 63 deletions
  1. 231 62
      main/exercice/exercise.class.php
  2. 6 1
      main/inc/lib/exercise_show_functions.lib.php

+ 231 - 62
main/exercice/exercise.class.php

@@ -2599,85 +2599,253 @@ class Exercise
                     }
                     break;
                 case FILL_IN_BLANKS:
-
-                    // 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
+                    $str = '';
                     if ($from_database) {
                         $sql = "SELECT answer
-                                FROM $TBL_TRACK_ATTEMPT
-                                WHERE
-                                    exe_id = $exeId AND
-                                    question_id= ".intval($questionId);
+                                    FROM $TBL_TRACK_ATTEMPT
+                                    WHERE
+                                        exe_id = $exeId AND
+                                        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]) : '';
+                    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."
+                                          WHERE
+                                            exe_id = '".$exeId."' AND
+                                            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();
 
-                            // 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)
-                                );
+                        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
+                                }
                             }
 
-                            $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;
+                            // 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];
                             }
-                            $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;
-                                    }
+                        // 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
+                                    FROM $TBL_TRACK_ATTEMPT
+                                    WHERE
+                                        exe_id = $exeId AND
+                                        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;
                             }
-                            $listCorrectAnswers['studentanswer'][$i] = $studentAnswer;
-                            if (!$found) {
-                                $listCorrectAnswers['studentscore'][$i] = 0;
-                            } else {
-                                $listCorrectAnswers['studentscore'][$i] = 1;
+                        } 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
+                        );
                     }
 
-                    $answer = FillBlanks::getAnswerInStudentAttempt($listCorrectAnswers);
                     break;
                 // for calculated answer
                 case CALCULATED_ANSWER:
@@ -3426,7 +3594,8 @@ class Exercise
                                 $answer,
                                 $exeId,
                                 $questionId,
-                                $results_disabled
+                                $results_disabled,
+                                $str
                             );
                             break;
                         case CALCULATED_ANSWER:

+ 6 - 1
main/inc/lib/exercise_show_functions.lib.php

@@ -23,11 +23,16 @@ class ExerciseShowFunctions
 	 * @param int       Exercise ID
 	 * @param int       Question ID
      * @param int $resultsDisabled
+     * @param string $originalStudentAnswer
 	 * @return void
 	 */
-	public static function display_fill_in_blanks_answer($feedbackType, $answer, $id, $questionId, $resultsDisabled)
+	public static function display_fill_in_blanks_answer($feedbackType, $answer, $id, $questionId, $resultsDisabled, $originalStudentAnswer = '')
     {
         $answerHTML = FillBlanks::getHtmlDisplayForAnswer($answer, $resultsDisabled);
+        if (strpos($originalStudentAnswer, 'font color') !== false) {
+            $answerHTML = $originalStudentAnswer;
+        }
+
         if (empty($id)) {
             echo '<tr><td>';
             echo Security::remove_XSS($answerHTML, COURSEMANAGERLOWSECURITY);