quiz-6.0.0-alpha4/modules/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceResponse.php

modules/quiz_multichoice/src/Plugin/quiz/QuizQuestion/MultichoiceResponse.php
<?php

namespace Drupal\quiz_multichoice\Plugin\quiz\QuizQuestion;

use Drupal\quiz\Entity\QuizResultAnswer;
use Drupal\quiz\Util\QuizUtil;
use function check_markup;

/**
 * Extension of QuizQuestionResponse.
 */
class MultichoiceResponse extends QuizResultAnswer {

  /**
   * {@inheritdoc}
   */
  public function score(array $response): ?int {
    if (!is_array($response['answer']['user_answer'])) {
      $selected_vids = [$response['answer']['user_answer']];
    }
    else {
      $selected_vids = $response['answer']['user_answer'];
    }

    // Reset whatever was here already.
    $this->get('multichoice_answer')->setValue(NULL);

    // The answer ID is the revision ID of the Paragraph item of the MCQ.
    // Fun!
    foreach ($selected_vids as $vid) {
      // Loop through all selected answers and append them to the paragraph
      // revision reference.
      $this->get('multichoice_answer')->appendItem($vid);
    }

    $simple = $this->getQuizQuestion()->get('choice_boolean')->getString();
    $multi = $this->getQuizQuestion()->get('choice_multi')->getString();

    // Set score at 1 for simple scoring, 0 for regular scoring.
    $score = $simple ? 1 : 0;

    $alternatives = $this->getQuizQuestion()
      ->get('alternatives')
      ->referencedEntities();

    foreach ($alternatives as $alternative) {
      // Take action on each alternative being selected (or not).
      $vid = $alternative->getRevisionId();
      // If this alternative was selected.
      $selected = in_array($vid, $selected_vids);
      $correct = $alternative->get('multichoice_correct')->getString();

      if ($simple) {
        if ($selected && !$correct) {
          // Selected this alt, simple scoring on, and the alt was
          // incorrect. Answer is wrong.
          $this->setEvaluated();
          return 0;
        }

        if (!$selected && $correct) {
          // Did not select this alt, simple scoring on, and the alt was
          // correct. Answer is wrong.
          $this->setEvaluated();
          return 0;
        }
      }
      else {
        if ($selected && $correct && !$multi) {
          // User selected a correct answer and this is not a multiple answer
          // question. User gets the point value of the question.
          $this->setEvaluated();
          return $alternative->get('multichoice_score_chosen')->getString();
        }

        if ($multi) {
          // In multiple answer questions we add (or subtract) some points based
          // on what answers they selected.
          $score += $selected ? $alternative->get('multichoice_score_chosen')->getString() : $alternative->get('multichoice_score_not_chosen')->getString();
        }
      }
    }

    // Return the total points for a multiple answer question.
    $this->setEvaluated();
    return $score;
  }

  /**
   * {@inheritdoc}
   */
  public function getResponse() {
    $vids = [];
    foreach ($this->get('multichoice_answer')->getValue() as $alternative) {
      $vids[] = $alternative['value'];
    }
    return $vids;
  }

  /**
   * {@inheritdoc}
   */
  public function getFeedbackValues(): array {
    $simple_scoring = $this->getQuizQuestion()
      ->get('choice_boolean')
      ->getString();

    $user_answers = $this->getResponse();

    $rows = [];
    $alternatives = $this->getQuizQuestion()
      ->get('alternatives')
      ->referencedEntities();
    foreach ($alternatives as $alternative) {
      $chosen = in_array($alternative->getRevisionId(), $user_answers);
      $not = $chosen ? '' : 'not_';
      $chosen_feedback = $alternative->{"multichoice_feedback_{$not}chosen"};
      $correct = $alternative->multichoice_score_chosen->value > 0;
      $icon_correct = $correct ? QuizUtil::icon('correct') : QuizUtil::icon('incorrect');

      $rows[] = [
        'status' => [
          'correct' => $correct,
          'chosen' => $chosen,
        ],
        'data' => [
          'choice' => check_markup($alternative->multichoice_answer->value, $alternative->multichoice_answer->format),
          'attempt' => $chosen ? QuizUtil::icon('selected') : '',
          'correct' => $icon_correct,
          'score' => (int) $alternative->{"multichoice_score_{$not}chosen"}->value,
          'answer_feedback' => check_markup((string) $chosen_feedback->value, $chosen_feedback->format),
          'question_feedback' => 'Question feedback',
          'solution' => $correct ? QuizUtil::icon('should') : ($simple_scoring ? QuizUtil::icon('should-not') : ''),
          'quiz_feedback' => 'Quiz feedback',
        ],
      ];
    }

    return $rows;
  }

  /**
   * Order the alternatives according to the choice order stored in the db.
   *
   * @param array $alternatives
   *   The alternatives to be ordered.
   */
  protected function orderAlternatives(array &$alternatives): void {
    if (!$this->question->choice_random) {
      return;
    }
    // @todo Drupal Rector Notice: Please delete the following comment after you've made any necessary changes.
    // You will need to use `\Drupal\core\Database\Database::getConnection()`
    // if you do not yet have access to the container here.
    $result = \Drupal::database()
      ->query('SELECT choice_order FROM {quiz_multichoice_user_answers}
            WHERE result_answer_id = :raid', [':raid' => $this->result_answer_id])
      ->fetchField();
    if (!$result) {
      return;
    }
    $order = explode(',', $result);
    $newAlternatives = [];
    foreach ($order as $value) {
      foreach ($alternatives as $alternative) {
        if ($alternative['id'] == $value) {
          $newAlternatives[] = $alternative;
          break;
        }
      }
    }
    $alternatives = $newAlternatives;
  }

  /**
   * Get answers for a question in a result.
   *
   * This static method assists in building views for the mass export of
   * question answers.
   *
   * @see views_handler_field_prerender_list
   */
  public static function viewsGetAnswers(array $result_answer_ids = []): array {
    $items = [];

    foreach (QuizResultAnswer::loadMultiple($result_answer_ids) as $qra) {
      foreach ($qra->getResponse() as $vid) {
        if ($vid) {
          /** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
          $storage = \Drupal::entityTypeManager()->getStorage('paragraph');
          /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
          $paragraph = $storage->loadRevision($vid);
          $answer = trim(strip_tags($paragraph->get('multichoice_answer')->value));
          $items[$qra->getQuizResultId()][] = ['answer' => $answer];
        }
      }
    }

    return $items;
  }

}

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

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