[ Index ]

PHP Cross Reference of moodle-2.8

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  
 191  /**
 192   * Subclass for generating the bits of output specific to multiple choice
 193   * single questions.
 194   *
 195   * @copyright  2009 The Open University
 196   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 197   */
 198  class qtype_multichoice_single_renderer extends qtype_multichoice_renderer_base {
 199      protected function get_input_type() {
 200          return 'radio';
 201      }
 202  
 203      protected function get_input_name(question_attempt $qa, $value) {
 204          return $qa->get_qt_field_name('answer');
 205      }
 206  
 207      protected function get_input_value($value) {
 208          return $value;
 209      }
 210  
 211      protected function get_input_id(question_attempt $qa, $value) {
 212          return $qa->get_qt_field_name('answer' . $value);
 213      }
 214  
 215      protected function is_right(question_answer $ans) {
 216          return $ans->fraction;
 217      }
 218  
 219      protected function prompt() {
 220          return get_string('selectone', 'qtype_multichoice');
 221      }
 222  
 223      public function correct_response(question_attempt $qa) {
 224          $question = $qa->get_question();
 225  
 226          foreach ($question->answers as $ansid => $ans) {
 227              if (question_state::graded_state_for_fraction($ans->fraction) ==
 228                      question_state::$gradedright) {
 229                  return get_string('correctansweris', 'qtype_multichoice',
 230                          $question->make_html_inline($question->format_text($ans->answer, $ans->answerformat,
 231                                  $qa, 'question', 'answer', $ansid)));
 232              }
 233          }
 234  
 235          return '';
 236      }
 237  }
 238  
 239  /**
 240   * Subclass for generating the bits of output specific to multiple choice
 241   * multi=select questions.
 242   *
 243   * @copyright  2009 The Open University
 244   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 245   */
 246  class qtype_multichoice_multi_renderer extends qtype_multichoice_renderer_base {
 247      protected function get_input_type() {
 248          return 'checkbox';
 249      }
 250  
 251      protected function get_input_name(question_attempt $qa, $value) {
 252          return $qa->get_qt_field_name('choice' . $value);
 253      }
 254  
 255      protected function get_input_value($value) {
 256          return 1;
 257      }
 258  
 259      protected function get_input_id(question_attempt $qa, $value) {
 260          return $this->get_input_name($qa, $value);
 261      }
 262  
 263      protected function is_right(question_answer $ans) {
 264          if ($ans->fraction > 0) {
 265              return 1;
 266          } else {
 267              return 0;
 268          }
 269      }
 270  
 271      protected function prompt() {
 272          return get_string('selectmulti', 'qtype_multichoice');
 273      }
 274  
 275      public function correct_response(question_attempt $qa) {
 276          $question = $qa->get_question();
 277  
 278          $right = array();
 279          foreach ($question->answers as $ansid => $ans) {
 280              if ($ans->fraction > 0) {
 281                  $right[] = $question->make_html_inline($question->format_text($ans->answer, $ans->answerformat,
 282                          $qa, 'question', 'answer', $ansid));
 283              }
 284          }
 285  
 286          if (!empty($right)) {
 287                  return get_string('correctansweris', 'qtype_multichoice',
 288                          implode(', ', $right));
 289          }
 290          return '';
 291      }
 292  
 293      protected function num_parts_correct(question_attempt $qa) {
 294          if ($qa->get_question()->get_num_selected_choices($qa->get_last_qt_data()) >
 295                  $qa->get_question()->get_num_correct_choices()) {
 296              return get_string('toomanyselected', 'qtype_multichoice');
 297          }
 298  
 299          return parent::num_parts_correct($qa);
 300      }
 301  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1