View source
<?php
namespace Drupal\quiz\Controller;
use Drupal;
use Drupal\Core\Entity\Controller\EntityController;
use Drupal\quiz\Entity\Quiz;
use Drupal\quiz\Entity\QuizResult;
use Drupal\quiz\Entity\QuizResultAnswer;
use Drupal\quiz\Form\QuizQuestionAnsweringForm;
use Drupal\quiz\Form\QuizQuestionFeedbackForm;
use Drupal\quiz\Util\QuizUtil;
use function variable_get;
class QuizQuestionController extends EntityController {
function feedback(Quiz $quiz, $question_number) {
$form = Drupal::formBuilder()
->getForm(QuizQuestionFeedbackForm::class, $quiz, $question_number);
$page['body']['question'] = $form;
return $page;
}
function take(Quiz $quiz, $question_number) {
if (!empty($_SESSION['quiz'][$quiz
->id()]['result_id'])) {
$quiz_result = QuizResult::load($_SESSION['quiz'][$quiz
->id()]['result_id']);
$layout = $quiz_result
->getLayout();
$question_relationship = $layout[$question_number];
if (!empty($question_relationship->qqr_pid)) {
foreach ($layout as $pquestion) {
if ($pquestion->qqr_id == $question_relationship->qqr_pid) {
$question = Drupal::entityTypeManager()
->getStorage('quiz_question')
->loadRevision($pquestion
->get('question_vid')
->getString());
}
}
}
else {
$question = Drupal::entityTypeManager()
->getStorage('quiz_question')
->loadRevision($question_relationship
->get('question_vid')
->getString());
}
}
if (!isset($question)) {
unset($_SESSION['quiz'][$quiz
->id()]);
return [
'#markup' => 'Question disappeared or invalid session. Start over.',
];
drupal_goto("quiz/{$quiz->id()}");
}
$quiz_result
->setQuestion($question_number);
$quiz_result = QuizResult::load($_SESSION['quiz'][$quiz
->id()]['result_id']);
$questions = array();
$i = 0;
$found_pages = 0;
foreach ($quiz_result
->getLayout() as $idx => $question_relationship) {
if (empty($question_relationship->qqr_pid)) {
$questions[$idx] = ++$i;
$found_pages++;
}
if ($question
->id() == $question_relationship
->get('question_id')
->getString()) {
$current_page = $found_pages;
}
}
$content = array();
$content['progress'] = [
'#theme' => 'quiz_progress',
'#total' => count($questions),
'#current' => $current_page,
'#weight' => -50,
];
if (count($questions) < \Drupal::config('quiz.settings')
->get('pager_start', 100)) {
$selectbox = \Drupal::formBuilder()
->getForm('\\Drupal\\quiz\\Form\\QuizJumperForm', $quiz_result, $current_page, count($questions));
$content['jumper'] = $selectbox;
$content['jumper']['#prefix'] = 'Question';
$content['jumper']['#suffix'] = 'of ' . count($questions);
$content['jumper']['#attributes']['class'] = 'container-inline';
}
else {
$siblings = \Drupal::config('quiz.settings')
->get('pager_siblings');
$items[] = array(
'#wrapper_attributes' => array(
'class' => [
'pager__item',
'pager-first',
],
),
'data' => \Drupal\Core\Link::createFromRoute(t('first'), 'quiz.question.take', [
'quiz' => $quiz
->id(),
'question_number' => 1,
])
->toRenderable(),
);
foreach (_quiz_pagination_helper(count($questions), 1, $current_page, $siblings) as $i) {
if ($i == $current_page) {
$items[] = array(
'#wrapper_attributes' => array(
'class' => [
'pager__item',
'pager-current',
],
),
'data' => [
'#markup' => $current_page,
],
);
}
else {
$items[] = array(
'#wrapper_attributes' => array(
'class' => [
'pager__item',
'pager-item',
],
),
'data' => \Drupal\Core\Link::createFromRoute($i, 'quiz.question.take', [
'quiz' => $quiz
->id(),
'question_number' => $i,
])
->toRenderable(),
);
}
}
$items[] = array(
'#wrapper_attributes' => array(
'class' => [
'pager__item',
'pager-last',
],
),
'data' => \Drupal\Core\Link::createFromRoute(t('last'), 'quiz.question.take', [
'quiz' => $quiz
->id(),
'question_number' => count($questions),
])
->toRenderable(),
);
$content['pager'] = [
'#type' => 'html_tag',
'#tag' => 'nav',
'#attributes' => array(
'class' => array(
'pager',
),
'role' => 'navigation',
),
];
$content['pager']['links'] = [
'#theme' => 'item_list',
'#items' => $items,
'#attributes' => array(
'class' => array(
'pager__items',
),
),
];
}
if (function_exists('jquery_countdown_add') && \Drupal::config('quiz.settings')
->get('has_timer', 0) && $quiz->time_limit) {
jquery_countdown_add('.countdown', array(
'until' => $quiz_result->time_start + $quiz->time_limit - \Drupal::time()
->getRequestTime(),
'onExpiry' => 'quiz_finished',
'compact' => FALSE,
'layout' => t('Time left') . ': {hnn}{sep}{mnn}{sep}{snn}',
));
$button_op1 = drupal_json_encode(t('Finish'));
$button_op2 = drupal_json_encode(t('Next'));
$js = "\n function quiz_finished() {\n // Find all buttons with a name of 'op'.\n var buttons = jQuery('input[type=submit][name=op], button[type=submit][name=op]');\n // Filter out the ones that don't have the right op value.\n buttons = buttons.filter(function() {\n return this.value == {$button_op1} || this.value == {$button_op2};\n });\n if (buttons.length == 1) {\n // Since only one button was found, this must be it.\n buttons.click();\n }\n else {\n // Zero, or more than one buttons were found; fall back on a page refresh.\n window.location = window.location.href;\n }\n }\n ";
drupal_add_js($js, 'inline');
$content['body']['countdown']['#markup'] = '<div class="countdown"></div>';
}
$form = Drupal::formBuilder()
->getForm(QuizQuestionAnsweringForm::class, $question, $_SESSION['quiz'][$quiz
->id()]['result_id']);
$content['body']['question'] = $form;
return $content;
}
function checkAccess(Quiz $quiz, $question_number) {
return $this
->checkEntityAccess('take', $quiz, $question_number);
}
function checkFeedbackAccess(Quiz $quiz, $question_number) {
return $this
->checkEntityAccess('feedback', $quiz, $question_number);
}
function checkEntityAccess($op, $quiz, $question_number) {
$qra = $this
->numberToQuestionResultAnswer($quiz, $question_number);
return $qra && $qra
->access($op) ? \Drupal\Core\Access\AccessResultAllowed::allowed() : \Drupal\Core\Access\AccessResultForbidden::forbidden();
}
function numberToQuestionResultAnswer($quiz, $question_number) {
$quiz_result = QuizUtil::resultOrTemp($quiz);
$qra = $quiz_result
->getLayout()[$question_number];
return $qra;
}
}