closedquestion-8.x-3.x-dev/src/Question/CqOption.php

src/Question/CqOption.php
<?php

namespace Drupal\closedquestion\Question;

use Drupal\closedquestion\Question\Mapping\CqFeedback;

/**
 * Class CqOption.
 *
 * An option in a multiple choice question.
 *
 * @package Drupal\closedquestion\Question
 */
class CqOption {

  /**
   * The identifier of this option.
   *
   * @var string
   */
  private $identifier;

  /**
   * The html to show to the user.
   *
   * @var string
   */
  private $text = '';

  /**
   * Is this option (part of) the correct answer?
   *
   * 1 Yes
   * 0 No
   * -1 Selecting this option doesn't matter.
   *
   * @var int
   */
  private $correct = 0;

  /**
   * The list of CqFeedback items to use if this item is selected.
   *
   * @var \Drupal\closedquestion\Question\Mapping\CqFeedback[]
   */
  private $feedback = array();
  /**
   * The list of CqFeedback items to use if this item is not selected.
   *
   * @var \Drupal\closedquestion\Question\Mapping\CqFeedback[]
   */
  private $feedbackUnselected = array();
  /**
   * HTML for an extended description to use in for instance a mouse-over.
   *
   * @var string
   */
  private $description = '';

  /**
   * Creates a new CqOption.
   *
   * @param \DOMElement $node
   *   Containing the option definition.
   * @param CqQuestionInterface $context
   *   The question or other object that the mapping can query for
   *   things like the current answer, draggables, hotspots and the parsing of
   *   html.
   */
  public function __construct(\DOMElement $node, CqQuestionInterface $context) {
    /** @var \Drupal\closedquestion\Utility\XmlLib $xmlLib */
    $xmlLib = \Drupal::service('closedquestion.utility.xml_lib');

    foreach ($node->getElementsByTagName('choice') as $choice) {
      $this->text .= $xmlLib->getTextContent($choice, $context);
    }

    foreach ($node->getElementsByTagName('description') as $description) {
      $this->description .= $xmlLib->getTextContent($description, $context);
    }

    foreach ($node->getElementsByTagName('feedback') as $fb) {
      $this->feedback[] = CqFeedback::newCqFeedback($fb, $context);
    }

    foreach ($node->getElementsByTagName('feedbackunselected') as $fb) {
      $this->feedbackUnselected[] = CqFeedback::newCqFeedback($fb, $context);
    }

    $attribs = $node->attributes;
    $item = $attribs->getNamedItem('correct');
    if ($item !== NULL) {
      $this->correct = (int) $item->value;
    }
    $item = $attribs->getNamedItem('identifier');
    if ($item === NULL) {
      $item = $attribs->getNamedItem('id');
    }
    if ($item === NULL) {
      $item = $attribs->getNamedItem('name');
    }
    if ($item !== NULL) {
      $this->identifier = $item->nodeValue;
    }
  }

  /**
   * Getter for the identifier.
   *
   * @return int
   *   ID.
   */
  public function getIdentifier() {
    return $this->identifier;
  }

  /**
   * Getter for the text.
   *
   * @return string
   *   Text.
   */
  public function getText() {
    return $this->text;
  }

  /**
   * Getter for the description.
   *
   * @return string
   *   Description.
   */
  public function getDescription() {
    return $this->description;
  }

  /**
   * Is this option (part of) the correct answer?
   *
   * 1 Yes
   * 0 No
   * -1 Selecting this option doesn't matter.
   *
   * @return int
   *   Result of the check.
   */
  public function getCorrect() {
    return $this->correct;
  }

  /**
   * Check if the user gave the correct answer for this option.
   *
   * @param string $answer
   *   A string longer than 1 character if the option is selected, a string of 1
   *   character or shorter of the option is not selected.
   *
   * @return bool
   *   TRUE if answer is correct.
   */
  public function correctlyAnswered($answer) {
    if (mb_strlen($answer) <= 1 && $this->correct != 0) {
      return FALSE;
    }
    if (mb_strlen($answer) > 1 && $this->correct == 0) {
      return FALSE;
    }

    return TRUE;
  }

  /**
   * Returns feedback items.
   *
   * Return the relevant feedback items for the given number of tries and the
   * given selected status.
   *
   * @param int $tries
   *   The number of times the student already tried to answer this question.
   * @param bool $selected
   *   Has the student selected this option? Defaults to TRUE.
   *
   * @return \Drupal\closedquestion\Question\Mapping\CqFeedback[]
   *   Feedback items.
   */
  public function getFeedback($tries, $selected = TRUE) {
    $retVal = array();
    if ($selected) {
      foreach ($this->feedback as $fb) {
        if ($fb->inRange($tries)) {
          $retVal[] = $fb;
        }
      }
    }
    else {
      foreach ($this->feedbackUnselected as $fb) {
        if ($fb->inRange($tries)) {
          $retVal[] = $fb;
        }
      }
    }
    return $retVal;
  }

  /**
   * Gets feedback.
   *
   * Getter for feedback, the full list of feedback items used when the option
   * is selected.
   *
   * @return \Drupal\closedquestion\Question\Mapping\CqFeedback[]
   *   Feedback items.
   */
  public function getFeedbackItems() {
    return $this->feedback;
  }

  /**
   * Gets unused feedback.
   *
   * Getter for feedbackUnselected, the full list of feedback items used when
   * the option is not selected.
   *
   * @return \Drupal\closedquestion\Question\Mapping\CqFeedback[]
   *   Feedback items.
   */
  public function getFeedbackUnselectedItems() {
    return $this->feedbackUnselected;
  }

  /**
   * Get all the text in the option, for easier reviewing for spelling, etc.
   *
   * @return array
   *   Themeable form array.
   */
  public function getAllText() {
    $retval = array();
    $retval['#theme'] = 'closedquestion_option';
    $retval['#identifier'] = $this->getIdentifier();
    $retval['#correct'] = $this->getCorrect();
    $retval['#text'] = $this->getText();
    $description = $this->getDescription();
    if ($description) {
      $retval['description'] = $description;
    }

    $feedback = $this->getFeedbackItems();
    if (count($feedback) > 0) {
      $retval['feedback'] = array(
        '#theme' => 'closedquestion_feedback_list',
        '#extended' => TRUE,
      );
      foreach ($feedback as $fbitem) {
        $retval['feedback']['items'][] = $fbitem->getAllText();
      }
    }

    $feedback = $this->getFeedbackUnselectedItems();
    if (count($feedback) > 0) {
      $retval['feedback_notselected'] = array(
        '#theme' => 'closedquestion_feedback_list',
        '#extended' => TRUE,
      );
      foreach ($feedback as $fbitem) {
        $retval['feedback_notselected']['items'][] = $fbitem->getAllText();
      }
    }
    return $retval;
  }

}

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

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