You are here

class ShortAnswerQuestion in Quiz 6.3

Same name and namespace in other branches
  1. 6.6 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion
  2. 6.4 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion
  3. 6.5 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion
  4. 7.6 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion
  5. 7 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion
  6. 7.4 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion
  7. 7.5 question_types/short_answer/short_answer.classes.inc \ShortAnswerQuestion

Implementation of QuizQuestion.

This could have extended long answer, except that that would have entailed adding long answer as a dependency.

Hierarchy

Expanded class hierarchy of ShortAnswerQuestion

1 string reference to 'ShortAnswerQuestion'
short_answer_quiz_question_info in question_types/short_answer/short_answer.module
Implementation of hook_quiz_question_info().

File

question_types/short_answer/short_answer.classes.inc, line 22
The main classes for the short answer question type.

View source
class ShortAnswerQuestion implements QuizQuestion {

  // Answer matching algorithms.
  const ANSWER_MATCH = 0;
  const ANSWER_INSENSITIVE_MATCH = 1;
  const ANSWER_REGEX = 2;
  const ANSWER_MANUAL = 3;

  // Field display types.
  const TEXT_ENTRY_TEXTFIELD = 0;
  const TEXT_ENTRY_TEXTAREA = 1;

  /**
   * The current node for this question.
   */
  protected $node = NULL;
  public function __construct($node) {
    $this->node = $node;
  }
  public function save($is_new = FALSE) {
    if (!isset($this->node->feedback)) {
      $this->node->feedback = '';
    }
    if ($is_new || $this->node->revision == 1) {
      $sql = 'INSERT INTO {quiz_short_answer_node_properties}
        (nid, vid, maximum_score, correct_answer, correct_answer_evaluation)
        VALUES (%d, %d, %d, \'%s\', %d)';
      db_query($sql, $this->node->nid, $this->node->vid, $this->node->maximum_score, $this->node->correct_answer, $this->node->correct_answer_evaluation);
    }
    else {
      $sql = 'UPDATE {quiz_short_answer_node_properties}
        SET maximum_score = %d, correct_answer = \'%s\', correct_answer_evaluation = %d
        WHERE nid = %d AND vid = %d';
      db_query($sql, $this->node->maximum_score, $this->node->correct_answer, $this->node->correct_answer_evaluation, $this->node->nid, $this->node->vid);
    }
  }
  public function validate($node, &$form) {
    $maximum_score = $node->maximum_score;
    if ((int) $maximum_score != $maximum_score || (int) $maximum_score < 0) {
      form_set_error('maximum_score', t('Score must be a positive integer (0 or higher).'));
    }
    if ($node->correct_answer_evaluation != self::ANSWER_MANUAL && empty($node->correct_answer)) {
      form_set_error('correct_answer_evaluation', t('An answer must be specified for any evaluation type other than manual scoring.'));
    }
  }
  public function delete($only_this_version = FALSE) {
    if ($only_this_version) {
      db_query('DELETE FROM {quiz_short_answer_node_properties} WHERE nid = %d AND vid = %d', $this->node->nid, $this->node->vid);
    }
    else {
      db_query('DELETE FROM {quiz_short_answer_node_properties} WHERE nid = %d', $this->node->nid);
    }
  }
  public function load() {
    $sql = 'SELECT maximum_score, correct_answer, correct_answer_evaluation
      FROM {quiz_short_answer_node_properties}
      WHERE nid = %d AND vid = %d';
    return db_fetch_object(db_query($sql, $this->node->nid, $this->node->vid));
  }
  public function view() {
    return $this
      ->getQuestionForm($this->node);
  }

  // This is called whenever a question is rendered, either
  // to an administrator or to a quiz taker.
  public function getQuestionForm($node, $context = NULL) {
    $form['question'] = array(
      '#type' => 'markup',
      '#value' => check_markup($node->body, $node->format),
    );
    $form['tries'] = array(
      '#type' => 'textfield',
      '#title' => t('Answer'),
      '#description' => t('Enter your answer here'),
      '#default_value' => isset($context['tries']) ? $context['tries'] : '',
      '#size' => 60,
      '#maxlength' => 256,
      '#required' => FALSE,
    );
    return $form;
  }
  public function getAdminForm($edit = NULL) {

    /*
    $form['short_answer_allow_regex'] = array(
      '#type' => 'checkbox',
      '#title' => t('Allow regular expression matching'),
      '#description' => t('If this is checked, quiz creators can use regular expressions for matching criteria.'),
      '#default_value' => variable_get('short_answer_allow_regex', TRUE),
    );
    return $form;
    */
    $form['empty'] = array(
      '#type' => 'markup',
      '#value' => t('There are currently no available configuration options.'),
    );
  }
  public function getCreationForm($edit) {
    $form['answer'] = array(
      '#type' => 'fieldset',
      '#title' => t('Answer'),
      '#description' => t('Provide the answer and the method by which the answer will be evaluated.'),
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
    );
    $form['answer']['correct_answer_evaluation'] = array(
      '#type' => 'radios',
      '#title' => t('Pick one'),
      '#description' => t('Choose a matching type.'),
      '#options' => array(
        self::ANSWER_MATCH => t('Exact match (answer must match case)'),
        self::ANSWER_INSENSITIVE_MATCH => t('Case insensitive match (answer need not match case)'),
        self::ANSWER_REGEX => t('Match against a regular expression (answer must match the supplied regular expression)'),
        self::ANSWER_MANUAL => t('Manually score matches (no automatic grading)'),
      ),
      '#default_value' => isset($this->node->correct_answer_evaluation) ? $this->node->correct_answer_evaluation : self::ANSWER_MATCH,
      '#required' => FALSE,
    );
    $form['answer']['regex_box'] = array(
      '#type' => 'fieldset',
      '#title' => t('About regular expressions'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
    );
    $form['answer']['regex_box']['regex_help'] = array(
      '#type' => 'markup',
      '#value' => '<p>' . t('Regular expressions are an advanced syntax for pattern matching. They allow you to create a concise set of rules that must be met before a value can be considered a match.') . '</p><p>' . t('For more on regular expression syntax, visit !url.', array(
        '!url' => l('the PHP regular expressions documentation', 'http://www.php.net/manual/en/book.pcre.php'),
      )) . '</p>',
    );
    $form['answer']['correct_answer'] = array(
      '#type' => 'textfield',
      '#title' => t('Answer'),
      '#description' => t('Specify the answer. If this question is manually scored, no answer need be supplied.'),
      '#default_value' => isset($this->node->correct_answer) ? $this->node->correct_answer : '',
      '#size' => 60,
      '#maxlength' => 256,
      '#required' => FALSE,
    );
    $form['answer']['maximum_score'] = array(
      '#type' => 'textfield',
      '#title' => t('Maximum score'),
      '#description' => t('If this is automatically graded, this will be treated as an "all or nothing" score. Manual grading may assign any whole number value between 0 and this number.'),
      '#default_value' => isset($this->node->maximum_score) ? $this->node->maximum_score : 1,
      '#size' => 3,
      '#maxlength' => 3,
      '#required' => FALSE,
    );
    return $form;
  }
  public function getMaximumScore() {
    return $this->node->maximum_score;
  }

  /**
   * Evaluate the correctness of an answer based on the correct answer and evaluation method.
   */
  public function evaluateAnswer($user_answer) {
    $score = 0;
    switch ($this->node->correct_answer_evaluation) {
      case self::ANSWER_MATCH:
        if ($user_answer == $this->node->correct_answer) {
          $score = $this->node->maximum_score;
        }
        break;
      case self::ANSWER_INSENSITIVE_MATCH:
        if (drupal_strtolower($user_answer) == drupal_strtolower($this->node->correct_answer)) {
          $score = $this->node->maximum_score;
        }
        break;
      case self::ANSWER_REGEX:

        //drupal_set_message('Regex is: ' . $this->node->correct_answer, 'status');
        if (preg_match($this->node->correct_answer, $user_answer) > 0) {
          $score = $this->node->maximum_score;
        }
        break;
    }
    return $score;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ShortAnswerQuestion::$node protected property The current node for this question.
ShortAnswerQuestion::ANSWER_INSENSITIVE_MATCH constant
ShortAnswerQuestion::ANSWER_MANUAL constant
ShortAnswerQuestion::ANSWER_MATCH constant
ShortAnswerQuestion::ANSWER_REGEX constant
ShortAnswerQuestion::delete public function Deletes a question from the database. Overrides QuizQuestion::delete
ShortAnswerQuestion::evaluateAnswer public function Evaluate the correctness of an answer based on the correct answer and evaluation method.
ShortAnswerQuestion::getAdminForm public function Get the form that contains admin settings for this question type. Overrides QuizQuestion::getAdminForm
ShortAnswerQuestion::getCreationForm public function Get the form used to create a new question. Overrides QuizQuestion::getCreationForm
ShortAnswerQuestion::getMaximumScore public function Get the maximum possible score for this question. Overrides QuizQuestion::getMaximumScore
ShortAnswerQuestion::getQuestionForm public function Get the form that will be displayed to the test-taking user. Overrides QuizQuestion::getQuestionForm
ShortAnswerQuestion::load public function Retrieve information about the question and add it to the node. Overrides QuizQuestion::load
ShortAnswerQuestion::save public function Responsible for handling insert/update of question-specific data. This is typically called from within the Node API, so there is no need to save the node. This function is only responsible for saving data specific to the implement ation. Overrides QuizQuestion::save
ShortAnswerQuestion::TEXT_ENTRY_TEXTAREA constant
ShortAnswerQuestion::TEXT_ENTRY_TEXTFIELD constant
ShortAnswerQuestion::validate public function Provides validation for question before it is created. Overrides QuizQuestion::validate
ShortAnswerQuestion::view public function Retrieve information relevant for viewing the node. This data is generally added to the node's extra field. Overrides QuizQuestion::view
ShortAnswerQuestion::__construct public function Construct a new quiz question. Overrides QuizQuestion::__construct