quiz-6.0.0-alpha4/modules/quiz_matching/src/Plugin/quiz/QuizQuestion/MatchingQuestion.php

modules/quiz_matching/src/Plugin/quiz/QuizQuestion/MatchingQuestion.php
<?php

namespace Drupal\quiz_matching\Plugin\quiz\QuizQuestion;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\quiz\Attribute\QuizQuestion as QuizQuestionAttribute;
use Drupal\quiz\Entity\QuizQuestion;
use Drupal\quiz\Entity\QuizResultAnswer;

/**
 * Matching classes.
 *
 * This module uses the question interface to define the matching question type.
 *
 * A Matching node defines a series of questions and answers and requires the
 * userto associate each answer with a question.
 */
#[QuizQuestionAttribute(
  id: 'matching',
  label: new TranslatableMarkup('Matching question'),
  handlers: ['response' => MatchingResponse::class],
)]
class MatchingQuestion extends QuizQuestion {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function getAnsweringForm(FormStateInterface $form_state, QuizResultAnswer $quizQuestionResultAnswer): array {
    $form = parent::getAnsweringForm($form_state, $quizQuestionResultAnswer);

    $answers[''] = '';
    $questions = [];
    foreach ($this->get('quiz_matching')->referencedEntities() as $alternative) {
      /** @var \Drupal\paragraphs\Entity\Paragraph $alternative */
      $questions[$alternative->getRevisionId()] = $alternative->get('matching_question')->getString();
      $answers[$alternative->getRevisionId()] = $alternative->get('matching_answer')->getString();
    }

    foreach ($questions as $id => $question) {
      // Build options list.
      $form['user_answer'][$id] = [
        '#title' => $question,
        '#type' => 'select',
        '#options' => $answers,
      ];
    }

    if ($paragraphs = $quizQuestionResultAnswer->getResponse()) {
      // If this question already has been answered.
      foreach ($paragraphs as $paragraph) {
        if ($paragraph->get('matching_user_answer')->value) {
          $form['user_answer'][$paragraph->get('matching_user_question')->value]['#default_value'] = $paragraph->get('matching_user_answer')->value;
        }
      }
    }

    if (\Drupal::config('quiz_matching.settings')->get('shuffle')) {
      $form['user_answer'] = $this->customShuffle($form['user_answer']);
    }
    $form['scoring_info'] = [
      '#access' => !empty($this->get('choice_penalty')->getString()),
      '#markup' => '<p><em>' . $this->t('You lose points by selecting incorrect options. You may leave an option blank to avoid losing points.') . '</em></p>',
    ];
    return $form;
  }

  /**
   * Question response validator.
   */
  public static function getAnsweringFormValidate(array &$element, FormStateInterface $form_state): void {
    $values = $form_state->getValues();
    $id = $element['#quiz_result_answer']->getQuizQuestion()->id();
    if (!array_filter($values['question'][$id]['answer']['user_answer'])) {
      $form_state->setError($element, t('You need to match at least one of the items.'));
    }
  }

  /**
   * Shuffles an array, but keep the keys.
   *
   * @param array $array
   *   Array to be shuffled.
   *
   * @return array
   *   A shuffled version of the array with keys preserved.
   */
  private function customShuffle(array $array = []): array {
    $new_array = [];
    while (count($array)) {
      $element = array_rand($array);
      $new_array[$element] = $array[$element];
      unset($array[$element]);
    }
    return $new_array;
  }

  /**
   * {@inheritdoc}
   */
  public function getMaximumScore(): int {
    return count($this->get('quiz_matching')->referencedEntities());
  }

  /**
   * Get the correct answers for this question.
   *
   * @return array
   *   Array of correct answers
   */
  public function getCorrectAnswer(): array {
    $correct_answers = [];
    foreach ($this->get('quiz_matching')->referencedEntities() as $entity) {
      $correct_answers[$entity->getRevisionId()] = $entity;
    }
    return $correct_answers;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc