[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |