Browse Source

WIP: Fix calculated question result see BT#14030

jmontoyaa 7 years ago
parent
commit
6679227bd0
2 changed files with 133 additions and 115 deletions
  1. 121 101
      main/exercise/exercise.class.php
  2. 12 14
      main/inc/lib/exercise.lib.php

+ 121 - 101
main/exercise/exercise.class.php

@@ -4027,120 +4027,135 @@ class Exercise
                     }
                     break;
                 case CALCULATED_ANSWER:
-                    $answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
-                    $preArray = explode('@@', $answer);
-                    $last = count($preArray) - 1;
-                    $answer = '';
-                    for ($k = 0; $k < $last; $k++) {
-                        $answer .= $preArray[$k];
-                    }
-                    $answerWeighting = [$answerWeighting];
-                    // we save the answer because it will be modified
-                    $temp = $answer;
-                    $answer = '';
-                    $j = 0;
-                    //initialise answer tags
-                    $userTags = $correctTags = $realText = [];
-                    // the loop will stop at the end of the text
-                    while (1) {
-                        // quits the loop if there are no more blanks (detect '[')
-                        if ($temp == false || ($pos = api_strpos($temp, '[')) === false) {
-                            // adds the end of the text
-                            $answer = $temp;
-                            $realText[] = $answer;
-                            break; //no more "blanks", quit the loop
-                        }
-                        // adds the piece of text that is before the blank
-                        //and ends with '[' into a general storage array
-                        $realText[] = api_substr($temp, 0, $pos + 1);
-                        $answer .= api_substr($temp, 0, $pos + 1);
-                        //take the string remaining (after the last "[" we found)
-                        $temp = api_substr($temp, $pos + 1);
-                        // quit the loop if there are no more blanks, and update $pos to the position of next ']'
-                        if (($pos = api_strpos($temp, ']')) === false) {
-                            // adds the end of the text
-                            $answer .= $temp;
-                            break;
+                    $calculatedAnswerList = Session::read('calculatedAnswerId');
+                    if (!empty($calculatedAnswerList)) {
+                        $answer = $objAnswerTmp->selectAnswer($calculatedAnswerList[$questionId]);
+                        $preArray = explode('@@', $answer);
+                        $last = count($preArray) - 1;
+                        $answer = '';
+                        for ($k = 0; $k < $last; $k++) {
+                            $answer .= $preArray[$k];
                         }
+                        $answerWeighting = [$answerWeighting];
+                        // we save the answer because it will be modified
+                        $temp = $answer;
+                        $answer = '';
+                        $j = 0;
+                        //initialise answer tags
+                        $userTags = $correctTags = $realText = [];
+                        // the loop will stop at the end of the text
+                        while (1) {
+                            // quits the loop if there are no more blanks (detect '[')
+                            if ($temp == false || ($pos = api_strpos($temp, '[')) === false) {
+                                // adds the end of the text
+                                $answer = $temp;
+                                $realText[] = $answer;
+                                break; //no more "blanks", quit the loop
+                            }
+                            // adds the piece of text that is before the blank
+                            //and ends with '[' into a general storage array
+                            $realText[] = api_substr($temp, 0, $pos + 1);
+                            $answer .= api_substr($temp, 0, $pos + 1);
+                            //take the string remaining (after the last "[" we found)
+                            $temp = api_substr($temp, $pos + 1);
+                            // quit the loop if there are no more blanks, and update $pos to the position of next ']'
+                            if (($pos = api_strpos($temp, ']')) === false) {
+                                // adds the end of the text
+                                $answer .= $temp;
+                                break;
+                            }
 
-                        if ($from_database) {
-                            $sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
+                            if ($from_database) {
+                                $sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
                                     WHERE
                                         exe_id = '".$exeId."' AND
                                         question_id = ".intval($questionId);
-                            $result = Database::query($sql);
-                            $str = Database::result($result, 0, 'answer');
+                                $result = Database::query($sql);
+                                $str = Database::result($result, 0, 'answer');
 
-                            api_preg_match_all('#\[([^[]*)\]#', $str, $arr);
-                            $str = str_replace('\r\n', '', $str);
-                            $choice = $arr[1];
-                            if (isset($choice[$j])) {
-                                $tmp = api_strrpos($choice[$j], ' / ');
+                                api_preg_match_all('#\[([^[]*)\]#', $str, $arr);
+                                $str = str_replace('\r\n', '', $str);
+                                $choice = $arr[1];
+                                if (isset($choice[$j])) {
+                                    $tmp = api_strrpos($choice[$j], ' / ');
 
-                                if ($tmp) {
-                                    $choice[$j] = api_substr($choice[$j], 0, $tmp);
+                                    if ($tmp) {
+                                        $choice[$j] = api_substr($choice[$j], 0, $tmp);
+                                    } else {
+                                        $tmp = ltrim($tmp, '[');
+                                        $tmp = rtrim($tmp, ']');
+                                    }
+
+                                    $choice[$j] = trim($choice[$j]);
+                                    // Needed to let characters ' and " to work as part of an answer
+                                    $choice[$j] = stripslashes($choice[$j]);
                                 } else {
-                                    $tmp = ltrim($tmp, '[');
-                                    $tmp = rtrim($tmp, ']');
+                                    $choice[$j] = null;
                                 }
-
-                                $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;
+                                // This value is the user input, not escaped while correct answer is escaped by fckeditor
+                                $choice[$j] = api_htmlentities(trim($choice[$j]));
                             }
-                        } else {
-                            // This value is the user input, not escaped while correct answer is escaped by fckeditor
-                            $choice[$j] = api_htmlentities(trim($choice[$j]));
-                        }
-                        $userTags[] = $choice[$j];
-                        //put the contents of the [] answer tag into correct_tags[]
-                        $correctTags[] = api_substr($temp, 0, $pos);
-                        $j++;
-                        $temp = api_substr($temp, $pos + 1);
-                    }
-                    $answer = '';
-                    $realCorrectTags = $correctTags;
-                    $calculatedStatus = Display::label(get_lang('Incorrect'), 'danger');
-                    $expectedAnswer = '';
-                    $calculatedChoice = '';
-
-                    for ($i = 0; $i < count($realCorrectTags); $i++) {
-                        if ($i == 0) {
-                            $answer .= $realText[0];
-                        }
-                        // Needed to parse ' and " characters
-                        $userTags[$i] = stripslashes($userTags[$i]);
-                        if ($correctTags[$i] == $userTags[$i]) {
-                            // gives the related weighting to the student
-                            $questionScore += $answerWeighting[$i];
-                            // increments total score
-                            $totalScore += $answerWeighting[$i];
-                            // adds the word in green at the end of the string
-                            $answer .= $correctTags[$i];
-                            $calculatedChoice = $correctTags[$i];
-                        } elseif (!empty($userTags[$i])) {
-                            // else if the word entered by the student IS NOT the same as
-                            // the one defined by the professor
-                            // adds the word in red at the end of the string, and strikes it
-                            $answer .= '<font color="red"><s>' . $userTags[$i] . '</s></font>';
-                            $calculatedChoice = $userTags[$i];
-                        } else {
-                            // adds a tabulation if no word has been typed by the student
-                            $answer .= ''; // remove &nbsp; that causes issue
+                            $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);
                         }
-                        // adds the correct word, followed by ] to close the blank
+                        $answer = '';
+                        $realCorrectTags = $correctTags;
+                        $calculatedStatus = Display::label(get_lang('Incorrect'), 'danger');
+                        $expectedAnswer = '';
+                        $calculatedChoice = '';
 
-                        if ($this->results_disabled != EXERCISE_FEEDBACK_TYPE_EXAM) {
-                            $answer .= ' / <font color="green"><b>'.$realCorrectTags[$i].'</b></font>';
-                            $calculatedStatus = Display::label(get_lang('Correct'), 'success');
-                            $expectedAnswer = $realCorrectTags[$i];
-                        }
-                        $answer .= ']';
+                        for ($i = 0; $i < count($realCorrectTags); $i++) {
+                            if ($i == 0) {
+                                $answer .= $realText[0];
+                            }
+                            // Needed to parse ' and " characters
+                            $userTags[$i] = stripslashes($userTags[$i]);
+                            if ($correctTags[$i] == $userTags[$i]) {
+                                // gives the related weighting to the student
+                                $questionScore += $answerWeighting[$i];
+                                // increments total score
+                                $totalScore += $answerWeighting[$i];
+                                // adds the word in green at the end of the string
+                                $answer .= $correctTags[$i];
+                                $calculatedChoice = $correctTags[$i];
+                            } elseif (!empty($userTags[$i])) {
+                                // else if the word entered by the student IS NOT the same as
+                                // the one defined by the professor
+                                // adds the word in red at the end of the string, and strikes it
+                                $answer .= '<font color="red"><s>' . $userTags[$i] . '</s></font>';
+                                $calculatedChoice = $userTags[$i];
+                            } else {
+                                // adds a tabulation if no word has been typed by the student
+                                $answer .= ''; // remove &nbsp; that causes issue
+                            }
+                            // adds the correct word, followed by ] to close the blank
+
+                            if ($this->results_disabled != EXERCISE_FEEDBACK_TYPE_EXAM) {
+                                $answer .= ' / <font color="green"><b>'.$realCorrectTags[$i].'</b></font>';
+                                $calculatedStatus = Display::label(get_lang('Correct'), 'success');
+                                $expectedAnswer = $realCorrectTags[$i];
+                            }
+                            $answer .= ']';
 
-                        if (isset($realText[$i + 1])) {
-                            $answer .= $realText[$i + 1];
+                            if (isset($realText[$i + 1])) {
+                                $answer .= $realText[$i + 1];
+                            }
+                        }
+                    } else {
+                        if ($from_database) {
+                            $sql = "SELECT *
+                                FROM $TBL_TRACK_ATTEMPT
+                                WHERE
+                                    exe_id = $exeId AND
+                                    question_id= ".intval($questionId);
+                            $result = Database::query($sql);
+                            $resultData = Database::fetch_array($result, 'ASSOC');
+                            $answer = $resultData['answer'];
+                            $questionScore = $resultData['marks'];
                         }
                     }
                     break;
@@ -5676,7 +5691,12 @@ class Exercise
                     false,
                     $objQuestionTmp->getAbsoluteFilePath()
                 );
-            } elseif (in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, READING_COMPREHENSION])) {
+            } elseif (
+                in_array(
+                    $answerType,
+                    [UNIQUE_ANSWER, UNIQUE_ANSWER_IMAGE, UNIQUE_ANSWER_NO_OPTION, READING_COMPREHENSION]
+                )
+            ) {
                 $answer = $choice;
                 Event::saveQuestionAttempt($questionScore, $answer, $quesId, $exeId, 0, $this->id);
             //            } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {

+ 12 - 14
main/inc/lib/exercise.lib.php

@@ -661,18 +661,16 @@ class ExerciseLib
                             global $exe_id;
                             $trackAttempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
                             $sql = 'SELECT answer FROM '.$trackAttempts.'
-                                    WHERE exe_id=' . $exe_id.' AND question_id='.$questionId;
+                                    WHERE exe_id='.$exe_id.' AND question_id='.$questionId;
                             $rsLastAttempt = Database::query($sql);
                             $rowLastAttempt = Database::fetch_array($rsLastAttempt);
                             $answer = $rowLastAttempt['answer'];
                             if (empty($answer)) {
-                                $_SESSION['calculatedAnswerId'][$questionId] = mt_rand(
-                                    1,
-                                    $nbrAnswers
-                                );
-                                $answer = $objAnswerTmp->selectAnswer(
-                                    $_SESSION['calculatedAnswerId'][$questionId]
-                                );
+                                $randomValue = mt_rand(1, $nbrAnswers);
+                                $answer = $objAnswerTmp->selectAnswer($randomValue);
+                                $calculatedAnswer = Session::read('calculatedAnswerId');
+                                $calculatedAnswer[$questionId] = $randomValue;
+                                Session::write('calculatedAnswerId', $calculatedAnswer);
                             }
                         }
 
@@ -684,7 +682,8 @@ class ExerciseLib
                             $correctAnswerList
                         );
 
-                        // get student answer to display it if student go back to previous calculated answer question in a test
+                        // get student answer to display it if student go back to
+                        // previous calculated answer question in a test
                         if (isset($user_choice[0]['answer'])) {
                             api_preg_match_all(
                                 '/\[[^]]+\]/',
@@ -694,9 +693,7 @@ class ExerciseLib
                             $studentAnswerListTobecleaned = $studentAnswerList[0];
                             $studentAnswerList = [];
 
-                            for ($i = 0; $i < count(
-                                $studentAnswerListTobecleaned
-                            ); $i++) {
+                            for ($i = 0; $i < count($studentAnswerListTobecleaned); $i++) {
                                 $answerCorrected = $studentAnswerListTobecleaned[$i];
                                 $answerCorrected = api_preg_replace(
                                     '| / <font color="green"><b>.*$|',
@@ -723,7 +720,8 @@ class ExerciseLib
                             }
                         }
 
-                        // If display preview of answer in test view for exemple, set the student answer to the correct answers
+                        // If display preview of answer in test view for exaemple,
+                        // set the student answer to the correct answers
                         if ($debug_mark_answer) {
                             // contain the rights answers surronded with brackets
                             $studentAnswerList = $correctAnswerList[0];
@@ -742,7 +740,7 @@ class ExerciseLib
                             ' '.$answer.' '
                         );
                         if (!empty($correctAnswerList) && !empty($studentAnswerList)) {
-                            $answer = "";
+                            $answer = '';
                             $i = 0;
                             foreach ($studentAnswerList as $studentItem) {
                                 // remove surronding brackets