Browse Source

Fix recalculate exercise in order to get the correct result BT#14870

Julio Montoya 6 years ago
parent
commit
592ec636bb
2 changed files with 92 additions and 51 deletions
  1. 16 12
      main/exercise/exercise.class.php
  2. 76 39
      main/exercise/recalculate.php

+ 16 - 12
main/exercise/exercise.class.php

@@ -3309,15 +3309,16 @@ class Exercise
      *
      * @param int    $exeId
      * @param int    $questionId
-     * @param mixed  $choice                                    the user-selected option
-     * @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 mixed  $choice                    the user-selected option
+     * @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
      * @param bool   $showTotalScoreAndUserChoicesInLastAttempt
+     * @param bool   $updateResults
      *
      * @todo    reduce parameters of this function
      *
@@ -3334,7 +3335,8 @@ class Exercise
         $show_result = true,
         $propagate_neg = 0,
         $hotspot_delineation_result = [],
-        $showTotalScoreAndUserChoicesInLastAttempt = true
+        $showTotalScoreAndUserChoicesInLastAttempt = true,
+        $updateResults = false
     ) {
         $debug = false;
         //needed in order to use in the exercise_attempt() for the time
@@ -3425,8 +3427,8 @@ class Exercise
 
         if ($answerType == MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
             $choiceTmp = $choice;
-            $choice = $choiceTmp["choice"];
-            $choiceDegreeCertainty = $choiceTmp["choiceDegreeCertainty"];
+            $choice = isset($choiceTmp['choice']) ? $choiceTmp['choice'] : '';
+            $choiceDegreeCertainty = isset($choiceTmp['choiceDegreeCertainty']) ? $choiceTmp['choiceDegreeCertainty'] : '';
         }
 
         if ($answerType == FREE_ANSWER ||
@@ -5650,11 +5652,12 @@ class Exercise
                                 Event::saveQuestionAttempt(
                                     $questionScore,
                                     $chosenAnswer.':'.$choice[$chosenAnswer].':'.
-                                        $choiceDegreeCertainty[$answerDegreeCertainty],
+                                    $choiceDegreeCertainty[$answerDegreeCertainty],
                                     $quesId,
                                     $exeId,
                                     $i,
-                                    $this->id
+                                    $this->id,
+                                    $updateResults
                                 );
                             }
                         } else {
@@ -5664,7 +5667,8 @@ class Exercise
                                 $quesId,
                                 $exeId,
                                 $i,
-                                $this->id
+                                $this->id,
+                                $updateResults
                             );
                         }
                         if ($debug) {

+ 76 - 39
main/exercise/recalculate.php

@@ -1,69 +1,106 @@
 <?php
 /* For licensing terms, see /license.txt */
 
+use Chamilo\CoreBundle\Entity\TrackEExercises;
+
 require_once __DIR__.'/../inc/global.inc.php';
 
 $isAllowedToEdit = api_is_allowed_to_edit(true, true);
 
 if (!$isAllowedToEdit) {
-    api_not_allowed(true);
     exit;
 }
 
 if (!isset($_REQUEST['user'], $_REQUEST['exercise'], $_REQUEST['id'])) {
-    api_not_allowed(true);
     exit;
 }
 
+$courseId = api_get_course_int_id();
+$sessionId = api_get_session_id();
 $em = Database::getManager();
 
-$trackedExercise = $em
-    ->getRepository('ChamiloCoreBundle:TrackEExercises')
-    ->find(intval($_REQUEST['id']));
+/** @var TrackEExercises $trackedExercise */
+$trackedExercise = $em->getRepository('ChamiloCoreBundle:TrackEExercises')->find($_REQUEST['id']);
 
-if ($trackedExercise->getExeUserId() != intval($_REQUEST['user']) ||
-    $trackedExercise->getExeExoId() != intval($_REQUEST['exercise'])
-) {
-    api_not_allowed(true);
+if (empty($trackedExercise)) {
     exit;
 }
 
-$attempts = $em->getRepository('ChamiloCoreBundle:TrackEAttempt')
-    ->findBy([
-        'exeId' => $trackedExercise->getExeId(),
-        'userId' => $trackedExercise->getExeUserId(),
-    ]);
+$studentId = $trackedExercise->getExeUserId();
+$exerciseId = $trackedExercise->getExeExoId();
+$exeId = $trackedExercise->getExeId();
 
-$newResult = 0;
-/** @var \Chamilo\CoreBundle\Entity\TrackEAttempt $attempt */
-foreach ($attempts as $attempt) {
-    $questionId = $attempt->getQuestionId();
+if ($studentId != intval($_REQUEST['user']) ||
+    $exerciseId != intval($_REQUEST['exercise'])
+) {
+    exit;
+}
 
-    $question = $em->find('ChamiloCourseBundle:CQuizQuestion', $questionId);
+$questionList = $trackedExercise->getDataTracking();
 
-    if (!$question) {
-        continue;
-    }
+if (empty($questionList)) {
+    exit;
+}
 
-    $answers = $em->getRepository('ChamiloCourseBundle:CQuizAnswer')->findBy([
-        'questionId' => $questionId,
-        'correct' => 1,
-    ]);
-
-    $newMarks = 0;
-    foreach ($answers as $answer) {
-        if ($answer->getId() != $attempt->getAnswer()) {
-            continue;
-        }
-        $newMarks += $answer->getPonderation();
+$questionList = explode(',', $questionList);
+
+$exercise = new Exercise($courseId);
+$exercise->read($exerciseId);
+$totalScore = 0;
+$totalWeight = 0;
+
+foreach ($questionList as $questionId) {
+    $question = Question::read($questionId, $courseId);
+    $totalWeight += $question->selectWeighting();
+
+    // We're inside *one* question. Go through each possible answer for this question
+    if ($question->type === MULTIPLE_ANSWER_TRUE_FALSE_DEGREE_CERTAINTY) {
+        $result = $exercise->manage_answer(
+            $exeId,
+            $questionId,
+            [],
+            'exercise_result',
+            [],
+            false,
+            true,
+            false,
+            $exercise->selectPropagateNeg(),
+            [],
+            [],
+            true
+        );
+    } else {
+        $result = $exercise->manage_answer(
+            $exeId,
+            $questionId,
+            [],
+            'exercise_result',
+            [],
+            false,
+            true,
+            false,
+            $exercise->selectPropagateNeg(),
+            [],
+            [],
+            true
+        );
     }
 
-    $newResult += $newMarks;
-    $attempt->setMarks($newMarks);
-    $em->merge($attempt);
+    //  Adding the new score.
+    $totalScore += $result['score'];
 }
 
-$trackedExercise->setExeResult($newResult);
+$remindList = $trackedExercise->getQuestionsToCheck();
+if (!empty($remindList)) {
+    $remindList = explode(',', $remindList);
+}
+
+$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+
+$sql = "UPDATE $table SET
+          exe_result = '$totalScore',
+          exe_weighting = '$totalWeight'
+        WHERE exe_id = $exeId";
+Database::query($sql);
 
-$em->merge($trackedExercise);
-$em->flush();
+echo $totalScore.'/'.$totalWeight;