You are here

public function MultichoiceResponse::score in Quiz 6.x

Same name and namespace in other branches
  1. 8.6 question_types/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceResponse.php \Drupal\quiz_multichoice\Plugin\quiz\QuizQuestion\MultichoiceResponse::score()
  2. 8.5 question_types/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceResponse.php \Drupal\quiz_multichoice\Plugin\quiz\QuizQuestion\MultichoiceResponse::score()

Calculate the unscaled score in points for this question response.

Parameters

array $values: A part of form state values with the question input from the user.

Return value

int|NULL The unscaled point value of the answer. If a point value is final, questions should make sure to run setEvaluated(). return NULL if the answer is not automatically scored.

Overrides QuizAnswerInterface::score

File

question_types/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceResponse.php, line 30

Class

MultichoiceResponse
Extension of QuizQuestionResponse.

Namespace

Drupal\quiz_multichoice\Plugin\quiz\QuizQuestion

Code

public function score(array $response) : ?int {
  if (!is_array($response['answer']['user_answer'])) {
    $selected_vids = [
      $response['answer']['user_answer'],
    ];
  }
  else {
    $selected_vids = $response['answer']['user_answer'];
  }

  // Reset whatever was here already.
  $this
    ->get('multichoice_answer')
    ->setValue(NULL);

  // The answer ID is the revision ID of the Paragraph item of the MCQ.
  // Fun!
  foreach ($selected_vids as $vid) {

    // Loop through all selected answers and append them to the paragraph
    // revision reference.
    $this
      ->get('multichoice_answer')
      ->appendItem($vid);
  }
  $simple = $this
    ->getQuizQuestion()
    ->get('choice_boolean')
    ->getString();
  $multi = $this
    ->getQuizQuestion()
    ->get('choice_multi')
    ->getString();
  $score = 0;
  $alternatives = $this
    ->getQuizQuestion()
    ->get('alternatives')
    ->referencedEntities();
  foreach ($alternatives as $alternative) {

    // Take action on each alternative being selected (or not).
    $vid = $alternative
      ->getRevisionId();

    // If this alternative was selected.
    $selected = in_array($vid, $selected_vids);
    $correct = $alternative
      ->get('multichoice_correct')
      ->getString();
    if (!$selected && $simple && $correct) {

      // Selected this answer, simple scoring on, and the answer was incorrect.
      $score = 0;
      break;
    }
    if ($selected && $correct && !$multi) {

      // User selected a correct answer and this is not a multiple answer
      // question. User gets the point value of the question.
      $score = $alternative
        ->get('multichoice_score_chosen')
        ->getString();
      break;
    }
    if ($multi) {

      // In multiple answer questions we sum up all the points.
      if ($selected) {

        // Add (or subtract) some points.
        $score += $alternative
          ->get('multichoice_score_chosen')
          ->getString();
      }
      else {
        $score += $alternative
          ->get('multichoice_score_not_chosen')
          ->getString();
      }
    }
  }
  $this
    ->setEvaluated();
  return $score;
}