[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/question/type/multichoice/ -> renderer.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Multiple choice question renderer classes.
  19   *
  20   * @package    qtype
  21   * @subpackage multichoice
  22   * @copyright  2009 The Open University
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  
  30  /**
  31   * Base class for generating the bits of output common to multiple choice
  32   * single and multiple questions.
  33   *
  34   * @copyright  2009 The Open University
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedback_renderer {
  38      protected abstract function get_input_type();
  39  
  40      protected abstract function get_input_name(question_attempt $qa, $value);
  41  
  42      protected abstract function get_input_value($value);
  43  
  44      protected abstract function get_input_id(question_attempt $qa, $value);
  45  
  46      /**
  47       * Whether a choice should be considered right, wrong or partially right.
  48       * @param question_answer $ans representing one of the choices.
  49       * @return fload 1.0, 0.0 or something in between, respectively.
  50       */
  51      protected abstract function is_right(question_answer $ans);
  52  
  53      protected abstract function prompt();
  54  
  55      public function formulation_and_controls(question_attempt $qa,
  56              question_display_options $options) {
  57  
  58          $question = $qa->get_question();
  59          $response = $question->get_response($qa);
  60  
  61          $inputname = $qa->get_qt_field_name('answer');
  62          $inputattributes = array(
  63              'type' => $this->get_input_type(),
  64              'name' => $inputname,
  65          );
  66  
  67          if ($options->readonly) {
  68              $inputattributes['disabled'] = 'disabled';
  69          }
  70  
  71          $radiobuttons = array();
  72          $feedbackimg = array();
  73          $feedback = array();
  74          $classes = array();
  75          foreach ($question->get_order($qa) as $value => $ansid) {
  76              $ans = $question->answers[$ansid];
  77              $inputattributes['name'] = $this->get_input_name($qa, $value);
  78              $inputattributes['value'] = $this->get_input_value($value);
  79              $inputattributes['id'] = $this->get_input_id($qa, $value);
  80              $isselected = $question->is_choice_selected($response, $value);
  81              if ($isselected) {
  82                  $inputattributes['checked'] = 'checked';
  83              } else {
  84                  unset($inputattributes['checked']);
  85              }
  86              $hidden = '';
  87              if (!$options->readonly && $this->get_input_type() == 'checkbox') {
  88                  $hidden = html_writer::empty_tag('input', array(
  89                      'type' => 'hidden',
  90                      'name' => $inputattributes['name'],
  91                      'value' => 0,
  92                  ));
  93              }
  94              $radiobuttons[] = $hidden . html_writer::empty_tag('input', $inputattributes) .
  95                      html_writer::tag('label',
  96                          $this->number_in_style($value, $question->answernumbering) .
  97                          $question->make_html_inline($question->format_text(
  98                                  $ans->answer, $ans->answerformat,
  99                                  $qa, 'question', 'answer', $ansid)),
 100                      array('for' => $inputattributes['id']));
 101  
 102              // Param $options->suppresschoicefeedback is a hack specific to the
 103              // oumultiresponse question type. It would be good to refactor to
 104              // avoid refering to it here.
 105              if ($options->feedback && empty($options->suppresschoicefeedback) &&
 106                      $isselected && trim($ans->feedback)) {
 107                  $feedback[] = html_writer::tag('div',
 108                          $question->make_html_inline($question->format_text(
 109                                  $ans->feedback, $ans->feedbackformat,
 110                                  $qa, 'question', 'answerfeedback', $ansid)),
 111                          array('class' => 'specificfeedback'));
 112              } else {
 113                  $feedback[] = '';
 114              }
 115              $class = 'r' . ($value % 2);
 116              if ($options->correctness && $isselected) {
 117                  $feedbackimg[] = $this->feedback_image($this->is_right($ans));
 118                  $class .= ' ' . $this->feedback_class($this->is_right($ans));
 119              } else {
 120                  $feedbackimg[] = '';
 121              }
 122              $classes[] = $class;
 123          }
 124  
 125          $result = '';
 126          $result .= html_writer::tag('div', $question->format_questiontext($qa),
 127                  array('class' => 'qtext'));
 128  
 129          $result .= html_writer::start_tag('div', array('class' => 'ablock'));
 130          $result .= html_writer::tag('div', $this->prompt(), array('class' => 'prompt'));
 131  
 132          $result .= html_writer::start_tag('div', array('class' => 'answer'));
 133          foreach ($radiobuttons as $key => $radio) {
 134              $result .= html_writer::tag('div', $radio . ' ' . $feedbackimg[$key] . $feedback[$key],
 135                      array('class' => $classes[$key])) . "\n";
 136          }
 137          $result .= html_writer::end_tag('div'); // Answer.
 138  
 139          $result .= html_writer::end_tag('div'); // Ablock.
 140  
 141          if ($qa->get_state() == question_state::$invalid) {
 142              $result .= html_writer::nonempty_tag('div',
 143                      $question->get_validation_error($qa->get_last_qt_data()),
 144                      array('class' => 'validationerror'));
 145          }
 146  
 147          return $result;
 148      }
 149  
 150      protected function number_html($qnum) {
 151          return $qnum . '. ';
 152      }
 153  
 154      /**
 155       * @param int $num The number, starting at 0.
 156       * @param string $style The style to render the number in. One of the
 157       * options returned by {@link qtype_multichoice:;get_numbering_styles()}.
 158       * @return string the number $num in the requested style.
 159       */
 160      protected function number_in_style($num, $style) {
 161          switch($style) {
 162              case 'abc':
 163                  $number = chr(ord('a') + $num);
 164                  break;
 165              case 'ABCD':
 166                  $number = chr(ord('A') + $num);
 167                  break;
 168              case '123':
 169                  $number = $num + 1;
 170                  break;
 171              case 'iii':
 172                  $number = question_utils::int_to_roman($num + 1);
 173                  break;
 174              case 'IIII':
 175                  $number = strtoupper(question_utils::int_to_roman($num + 1));
 176                  break;
 177              case 'none':
 178                  return '';
 179              default:
 180                  return 'ERR';
 181          }
 182          return $this->number_html($number);
 183      }
 184  
 185      public function specific_feedback(question_attempt $qa) {
 186          return $this->combined_feedback($qa);
 187      }
 188  
 189      /**
 190       * Function returns string based on number of correct answers
 191       * @param array $right An Array of correct responses to the current question
 192       * @return string based on number of correct responses
 193       */
 194      protected function correct_choices(array $right) {
 195          // Return appropriate string for single/multiple correct answer(s).
 196          if (count($right) == 1) {
 197                  return get_string('correctansweris', 'qtype_multichoice',
 198                          implode(', ', $right));
 199          } else if (count($right) > 1) {
 200                  return get_string('correctanswersare', 'qtype_multichoice',
 201                          implode(', ', $right));
 202          } else {
 203                  return "";
 204          }
 205      }
 206  }
 207  
 208  
 209  /**
 210   * Subclass for generating the bits of output specific to multiple choice
 211   * single questions.
 212   *
 213   * @copyright  2009 The Open University
 214   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 215   */
 216  class qtype_multichoice_single_renderer extends qtype_multichoice_renderer_base {
 217      protected function get_input_type() {
 218          return 'radio';
 219      }
 220  
 221      protected function get_input_name(question_attempt $qa, $value) {
 222          return $qa->get_qt_field_name('answer');
 223      }
 224  
 225      protected function get_input_value($value) {
 226          return $value;
 227      }
 228  
 229      protected function get_input_id(question_attempt $qa, $value) {
 230          return $qa->get_qt_field_name('answer' . $value);
 231      }
 232  
 233      protected function is_right(question_answer $ans) {
 234          return $ans->fraction;
 235      }
 236  
 237      protected function prompt() {
 238          return get_string('selectone', 'qtype_multichoice');
 239      }
 240  
 241      public function correct_response(question_attempt $qa) {
 242          $question = $qa->get_question();
 243  
 244          // Put all correct answers (100% grade) into $right.
 245          $right = array();
 246          foreach ($question->answers as $ansid => $ans) {
 247              if (question_state::graded_state_for_fraction($ans->fraction) ==
 248                      question_state::$gradedright) {
 249                  $right[] = $question->make_html_inline($question->format_text($ans->answer, $ans->answerformat,
 250                          $qa, 'question', 'answer', $ansid));
 251              }
 252          }
 253          return $this->correct_choices($right);
 254      }
 255  }
 256  
 257  /**
 258   * Subclass for generating the bits of output specific to multiple choice
 259   * multi=select questions.
 260   *
 261   * @copyright  2009 The Open University
 262   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 263   */
 264  class qtype_multichoice_multi_renderer extends qtype_multichoice_renderer_base {
 265      protected function get_input_type() {
 266          return 'checkbox';
 267      }
 268  
 269      protected function get_input_name(question_attempt $qa, $value) {
 270          return $qa->get_qt_field_name('choice' . $value);
 271      }
 272  
 273      protected function get_input_value($value) {
 274          return 1;
 275      }
 276  
 277      protected function get_input_id(question_attempt $qa, $value) {
 278          return $this->get_input_name($qa, $value);
 279      }
 280  
 281      protected function is_right(question_answer $ans) {
 282          if ($ans->fraction > 0) {
 283              return 1;
 284          } else {
 285              return 0;
 286          }
 287      }
 288  
 289      protected function prompt() {
 290          return get_string('selectmulti', 'qtype_multichoice');
 291      }
 292  
 293      public function correct_response(question_attempt $qa) {
 294          $question = $qa->get_question();
 295  
 296          $right = array();
 297          foreach ($question->answers as $ansid => $ans) {
 298              if ($ans->fraction > 0) {
 299                  $right[] = $question->make_html_inline($question->format_text($ans->answer, $ans->answerformat,
 300                          $qa, 'question', 'answer', $ansid));
 301              }
 302          }
 303          return $this->correct_choices($right);
 304      }
 305  
 306      protected function num_parts_correct(question_attempt $qa) {
 307          if ($qa->get_question()->get_num_selected_choices($qa->get_last_qt_data()) >
 308                  $qa->get_question()->get_num_correct_choices()) {
 309              return get_string('toomanyselected', 'qtype_multichoice');
 310          }
 311  
 312          return parent::num_parts_correct($qa);
 313      }
 314  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1