You are here

public function QuizQuestionAnsweringForm::submitForm in Quiz 8.5

Same name and namespace in other branches
  1. 8.6 src/Form/QuizQuestionAnsweringForm.php \Drupal\quiz\Form\QuizQuestionAnsweringForm::submitForm()
  2. 6.x src/Form/QuizQuestionAnsweringForm.php \Drupal\quiz\Form\QuizQuestionAnsweringForm::submitForm()

Submit handler for the question answering form.

There is no validation code here, but there may be feedback code for correct feedback.

Overrides FormInterface::submitForm

File

src/Form/QuizQuestionAnsweringForm.php, line 181

Class

QuizQuestionAnsweringForm

Namespace

Drupal\quiz\Form

Code

public function submitForm(array &$form, FormStateInterface $form_state) {
  $config = $this
    ->config('quiz.settings');
  $result_id = $form_state
    ->getBuildInfo()['args'][1];
  $feedback_count = 0;
  $quiz_result = QuizResult::load($result_id);
  $quiz = \Drupal::entityTypeManager()
    ->getStorage('quiz')
    ->loadRevision($quiz_result
    ->get('vid')
    ->getString());
  $time_reached = $quiz
    ->get('time_limit')
    ->getString() > 0 && \Drupal::time()
    ->getRequestTime() > $quiz_result
    ->get('time_start')
    ->getString() + $quiz
    ->get('time_limit')
    ->getString() + $config
    ->get('time_limit_buffer', 5);
  $layout = $quiz_result
    ->getLayout();
  if ($time_reached) {

    // Too late.
    // @todo move to quiz_question_answering_form_validate(), and then put all
    // the "quiz end" logic in a sharable place. We just need to not fire the
    // logic that saves all the users answers.
    \Drupal::messenger()
      ->addError(t('The last answer was not submitted, as the time ran out.'));
  }
  else {
    $submitted = $form_state
      ->getValue('question');
    foreach ($layout as $qra) {
      if (isset($submitted[$qra
        ->get('question_id')
        ->getString()])) {

        // User submitted a response to this question.
        $qqid = $qra
          ->get('question_id')
          ->getString();
        $qra
          ->set('answer_timestamp', \Drupal::time()
          ->getRequestTime());

        // Get the unscaled points awarded from the question response
        // implementation and then apply the weighted ratio in this quiz. For
        // example a MCQ question itself may be worth 4 points but worth 10
        // points in this quiz. A score of 2 would mean 5 points being
        // recorded.
        $qra->points_awarded = $qra
          ->score($form_state
          ->getValues()['question'][$qqid]) * $qra
          ->getWeightedRatio();

        // Mark question as not skipped, in case it was skipped previously.
        $qra->is_skipped = FALSE;

        // Mark as doubtful.
        $qra->is_doubtful = !empty($form_state
          ->getValues()['question'][$qqid]['is_doubtful']) ? 1 : 0;
        $qra
          ->save();

        // Does this question type have feedback? We need to track it across pages.
        $feedback_count += $qra
          ->getQuizQuestion()
          ->hasFeedback();

        // Increment the question position.
        $quiz_result
          ->setQuestion($qra
          ->get('number')
          ->getString() + 1);
      }
    }
  }

  // Wat do?
  $next_number = $_SESSION['quiz'][$quiz
    ->id()]['current'];
  if ($time_reached || !isset($layout[$_SESSION['quiz'][$quiz
    ->id()]['current']])) {

    // If this is the last question, finalize the quiz.
    $this
      ->submitFinalize($form, $form_state);
  }
  else {

    // No question feedback. Go to next question.
    $form_state
      ->setRedirect('quiz.question.take', [
      'quiz' => $quiz
        ->id(),
      'question_number' => $_SESSION['quiz'][$quiz
        ->id()]['current'],
    ]);
  }
  if ($quiz
    ->get('review_options')
    ->get(0) && !empty($quiz
    ->get('review_options')
    ->get(0)
    ->getValue()['question']) && array_filter($quiz
    ->get('review_options')
    ->get(0)
    ->getValue()['question']) && $feedback_count) {

    // This page contains questions that can provide feedback, and question
    // feedback is enabled on the quiz.
    $form_state
      ->setRedirect('quiz.question.feedback', [
      'quiz' => $quiz
        ->id(),
      'question_number' => $next_number - 1,
    ]);

    // @todo d8 this is used by ajax_quiz I think

    //$form_state['feedback'] = TRUE;
  }
}