public function QuizQuestionAnsweringForm::buildForm in Quiz 8.5
Same name and namespace in other branches
- 8.6 src/Form/QuizQuestionAnsweringForm.php \Drupal\quiz\Form\QuizQuestionAnsweringForm::buildForm()
- 6.x src/Form/QuizQuestionAnsweringForm.php \Drupal\quiz\Form\QuizQuestionAnsweringForm::buildForm()
Get the form to show to the quiz taker.
_state
Parameters
array $form:
array $questions: A list of question nodes to get answers from.
int $result_id: The result ID for this attempt.
Return value
array An renderable FAPI array.
Overrides FormInterface::buildForm
File
- src/
Form/ QuizQuestionAnsweringForm.php, line 26
Class
Namespace
Drupal\quiz\FormCode
public function buildForm(array $form, FormStateInterface $form_state) : array {
/* @var $questions \Drupal\quiz\Entity\QuizQuestion[] */
$questions = $form_state
->getBuildInfo()['args'][0];
$quiz_result = QuizResult::load($form_state
->getBuildInfo()['args'][1]);
$quiz = \Drupal::entityTypeManager()
->getStorage('quiz')
->loadRevision($quiz_result
->get('vid')
->getString());
// Take quiz and result in the form.
$form['#quiz'] = array(
'nid' => $quiz->nid,
'vid' => $quiz->vid,
);
$form['#quiz_result'] = $quiz_result;
if (!is_array($questions)) {
// One single question (or page?)
if ($questions
->bundle() == 'page') {
foreach ($quiz_result
->getLayout() as $qra) {
if ($qra
->get('question_id')
->getString() == $questions
->id()) {
// Found the page in the layout.
// Add the page as the first "question".
$questions = array(
$questions,
);
foreach ($quiz_result
->getLayout() as $qra2) {
// Get all page children.
if ($qra2->qqr_pid == $qra->qqr_id) {
// This question belongs in the requested page.
$questions[] = $qra2
->getQuizQuestion();
}
}
break;
}
}
}
else {
// Make this a page of 1 question.
$questions = array(
$questions
->id() => $questions,
);
}
}
$form['#attributes']['class'] = array(
'answering-form',
);
$form['#tree'] = TRUE;
foreach ($questions as $question) {
$class = Html::getClass('quiz-question-' . $question
->bundle());
// Element for a single question.
// @todo Instead of doing this load I think we can refer back to the layout.
$qra = $question
->getResponse($quiz_result);
$element = $question
->getAnsweringForm($form_state, $qra);
// Render the question using the "question" view mode.
$build = \Drupal::entityTypeManager()
->getViewBuilder('quiz_question')
->view($question, 'question');
$form['question'][$question
->id()] = array(
'#attributes' => array(
'class' => array(
$class,
),
),
'#type' => 'container',
'header' => !$qra
->get('display_number')
->isEmpty() ? array(
'#markup' => "<h2>" . t("Question @question", array(
'@question' => $qra
->get('display_number')
->getString(),
)) . "</h2>",
) : NULL,
'question' => $build,
'answer' => $element,
);
$form['question'][$question
->id()]['answer']['#quiz_result_answer'] = $qra;
$blank_and_change = $qra
->get('is_skipped')
->getString() && $quiz
->get('allow_change_blank')
->getString();
if (!$quiz
->get('allow_change')
->getString() && !$qra
->get('answer_timestamp')
->isEmpty()) {
if ($blank_and_change) {
// Allow it.
}
else {
// This question was already answered, or answering blank question is
// disabled.
$form['question'][$question
->id()]['#disabled'] = TRUE;
if (empty($form_state
->getUserInput())) {
// Only show message if not submitting.
\Drupal::messenger()
->addWarning(t('Changing answers is disabled.'));
}
}
}
if ($quiz
->get('mark_doubtful')
->getString() && $question
->isQuestion()) {
$form['question'][$question
->id()]['is_doubtful'] = array(
'#type' => 'checkbox',
'#title' => t('Doubtful?'),
'#default_value' => $qra
->get('is_doubtful')
->getString(),
);
}
}
$is_last = $quiz
->isLastQuestion();
$form['navigation']['#type'] = 'actions';
$form['navigation']['#theme'] = 'quiz_question_navigation_form';
$form['navigation']['submit_hidden'] = array(
'#weight' => -9999,
'#type' => 'submit',
'#value' => $is_last ? t('Finish') : t('Next'),
'#attributes' => array(
'style' => 'display: none',
),
);
if ($quiz
->get('backwards_navigation')
->getString() && $_SESSION['quiz'][$quiz
->id()]['current'] != 1) {
// Backwards navigation enabled, and we are looking at not the first
// question. @todo detect when on the first page.
$form['navigation']['back'] = array(
'#weight' => 10,
'#type' => 'submit',
'#value' => t('Back'),
'#submit' => array(
'::submitBack',
),
'#limit_validation_errors' => array(),
);
if ($is_last) {
$form['navigation']['#last'] = TRUE;
$form['navigation']['last_text'] = array(
'#weight' => 0,
'#markup' => '<p><em>' . t('This is the last question. Press Finish to deliver your answers') . '</em></p>',
);
}
}
$form['navigation']['submit'] = array(
'#weight' => 30,
'#type' => 'submit',
'#value' => $is_last ? t('Finish') : t('Next'),
'#ajax' => [],
);
if ($is_last && $quiz
->get('backwards_navigation')
->getString() && !$quiz
->get('repeat_until_correct')
->getString()) {
// Display a confirmation dialogue if this is the last question and a user
// is able to navigate backwards but not forced to answer correctly.
$form['#attributes']['class'][] = 'quiz-answer-confirm';
$form['#attributes']['data-confirm-message'] = t("By proceeding you won't be able to go back and edit your answers.");
$form['#attached']['library'][] = 'quiz/confirm';
}
if ($quiz
->get('allow_skipping')
->getString()) {
$form['navigation']['skip'] = array(
'#weight' => 20,
'#type' => 'submit',
'#value' => $is_last ? t('Leave blank and finish') : t('Leave blank'),
'#access' => $question->type == 'quiz_directions' ? FALSE : TRUE,
'#submit' => array(
'::submitBlank',
),
'#limit_validation_errors' => array(),
);
}
return $form;
}