quiz_maker-1.0.6/src/Plugin/QuizMaker/Question/MatchingQuestion.php

src/Plugin/QuizMaker/Question/MatchingQuestion.php
<?php

namespace Drupal\quiz_maker\Plugin\QuizMaker\Question;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\quiz_maker\Plugin\QuizMaker\QuestionPluginBase;
use Drupal\quiz_maker\QuestionResponseInterface;
use Drupal\quiz_maker\SimpleScoringQuestionInterface;
use Drupal\quiz_maker\Trait\SimpleScoringQuestionTrait;

/**
 * Plugin implementation of the question.
 *
 * @QuizMakerQuestion(
 *   id = "matching_question",
 *   label = @Translation("Matching question"),
 *   description = @Translation("Matching question."),
 * )
 */
class MatchingQuestion extends QuestionPluginBase implements SimpleScoringQuestionInterface {

  use StringTranslationTrait;
  use SimpleScoringQuestionTrait;

  /**
   * {@inheritDoc}
   */
  public function getAnsweringForm(QuestionResponseInterface|null $question_response = NULL, bool $allow_change_response = TRUE): array {
    $answers = $this->getEntity()->getAnswers();
    if ($answers) {
      $answer_form = [
        '#type' => 'container',
        '#attributes' => [
          'class' => ['matching-form'],
        ],
      ];

      // To build answer form we have to set unique names to get right response
      // in form submit, because quiz could have several question of the same
      // type.
      $answer_form['question_table_' . $this->entity->id()] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => ['question-table'],
        ],
      ];

      $answer_form['answer_table_' . $this->entity->id()] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => ['answer-table'],
        ],
      ];
      // The column of questions (non-draggable).
      $answer_form['question_table_' . $this->entity->id()]['question_column_' . $this->entity->id()] = $this->getMatchingTable($answers, 'getMatchingQuestion', $this->t('Question'), FALSE, FALSE);

      // The matching column of answers(draggable).
      // If question already has response - get answers from response,
      // otherwise get original answers and shuffle it.
      if ($question_response) {
        $answers = $this->entityTypeManager->getStorage('question_answer')->loadMultiple($question_response->getResponses());
        // When we get any error and answer array is empty.
        if (!$answers) {
          $answers = $this->getEntity()->getAnswers();
          shuffle($answers);
        }
      }
      else {
        $answers = $this->getEntity()->getAnswers();
        shuffle($answers);
      }

      $answer_form['answer_table_' . $this->entity->id()][$this->getQuestionAnswerWrapperId()] = $this->getMatchingTable($answers, 'getMatchingAnswer', $this->t('Answer'), $allow_change_response);

      return $answer_form;
    }

    return [];
  }

  /**
   * {@inheritDoc}
   */
  public function validateAnsweringForm(array &$form, FormStateInterface $form_state): void {
    // No need to validate, because answer will be gotten from default matching.
  }

  /**
   * {@inheritDoc}
   */
  public function getResponse(array &$form, FormStateInterface $form_state): array {
    $responses = parent::getResponse($form, $form_state);
    if (!$responses) {
      return [];
    }
    return array_keys($responses);
  }

  /**
   * Get Matching table.
   *
   * @param \Drupal\quiz_maker\Plugin\QuizMaker\Answer\MatchingAnswer[] $answers
   *   The Matching answers.
   * @param string $answer_function
   *   The matching answer function: 'getMatchingQuestion' or
   *   'getMatchingAnswer'.
   * @param mixed $title
   *   The table title.
   * @param bool $allow_change_response
   *   Allow to change response.
   * @param bool $draggable
   *   TRUE if table should be draggable.
   *
   * @return array
   *   The table.
   */
  private function getMatchingTable(array $answers, string $answer_function, mixed $title, bool $allow_change_response = TRUE, bool $draggable = TRUE): array {
    $table = [
      '#type' => 'table',
      '#header' => [
        $title,
      ],
      '#disabled' => !$allow_change_response,
    ];

    if ($draggable && $allow_change_response) {
      $table['#header'][] = $this->t('Weight');
      $table['#tabledrag'] = [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'table-sort-weight',
        ],
      ];
    }

    $i = 0;
    foreach ($answers as $answer) {
      /** @var \Drupal\quiz_maker\Entity\QuestionAnswer $answer */
      $answer_instance = $answer->getPluginInstance();
      $row = [
        'label' => [
          '#type' => 'html_tag',
          '#tag' => 'span',
          '#value' => $answer_instance->{$answer_function}(),
        ],
        '#attributes' => [
          'class' => ['draggable'],
        ],
      ];
      if ($draggable) {
        $row['weight'] = [
          '#type' => 'weight',
          '#title' => $this->t('Weight for @title', ['@title' => $answer->label()]),
          '#title_display' => 'invisible',
          '#default_value' => $i,
          '#attributes' => ['class' => ['table-sort-weight']],
        ];
      }
      $table[$answer->id()] = $row;
      $i++;
    }

    return $table;
  }

}

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

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