|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00027 defined('MOODLE_INTERNAL') || die(); 00028 00029 00037 abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedback_renderer { 00038 protected abstract function get_input_type(); 00039 00040 protected abstract function get_input_name(question_attempt $qa, $value); 00041 00042 protected abstract function get_input_value($value); 00043 00044 protected abstract function get_input_id(question_attempt $qa, $value); 00045 00051 protected abstract function is_right(question_answer $ans); 00052 00053 protected abstract function prompt(); 00054 00055 public function formulation_and_controls(question_attempt $qa, 00056 question_display_options $options) { 00057 00058 $question = $qa->get_question(); 00059 $response = $question->get_response($qa); 00060 00061 $inputname = $qa->get_qt_field_name('answer'); 00062 $inputattributes = array( 00063 'type' => $this->get_input_type(), 00064 'name' => $inputname, 00065 ); 00066 00067 if ($options->readonly) { 00068 $inputattributes['disabled'] = 'disabled'; 00069 } 00070 00071 $radiobuttons = array(); 00072 $feedbackimg = array(); 00073 $feedback = array(); 00074 $classes = array(); 00075 foreach ($question->get_order($qa) as $value => $ansid) { 00076 $ans = $question->answers[$ansid]; 00077 $inputattributes['name'] = $this->get_input_name($qa, $value); 00078 $inputattributes['value'] = $this->get_input_value($value); 00079 $inputattributes['id'] = $this->get_input_id($qa, $value); 00080 $isselected = $question->is_choice_selected($response, $value); 00081 if ($isselected) { 00082 $inputattributes['checked'] = 'checked'; 00083 } else { 00084 unset($inputattributes['checked']); 00085 } 00086 $hidden = ''; 00087 if (!$options->readonly && $this->get_input_type() == 'checkbox') { 00088 $hidden = html_writer::empty_tag('input', array( 00089 'type' => 'hidden', 00090 'name' => $inputattributes['name'], 00091 'value' => 0, 00092 )); 00093 } 00094 $radiobuttons[] = $hidden . html_writer::empty_tag('input', $inputattributes) . 00095 html_writer::tag('label', 00096 $this->number_in_style($value, $question->answernumbering) . 00097 $question->make_html_inline($question->format_text( 00098 $ans->answer, $ans->answerformat, 00099 $qa, 'question', 'answer', $ansid)), 00100 array('for' => $inputattributes['id'])); 00101 00102 // $options->suppresschoicefeedback is a hack specific to the 00103 // oumultiresponse question type. It would be good to refactor to 00104 // avoid refering to it here. 00105 if ($options->feedback && empty($options->suppresschoicefeedback) && 00106 $isselected && trim($ans->feedback)) { 00107 $feedback[] = html_writer::tag('div', 00108 $question->make_html_inline($question->format_text( 00109 $ans->feedback, $ans->feedbackformat, 00110 $qa, 'question', 'answerfeedback', $ansid)), 00111 array('class' => 'specificfeedback')); 00112 } else { 00113 $feedback[] = ''; 00114 } 00115 $class = 'r' . ($value % 2); 00116 if ($options->correctness && $isselected) { 00117 $feedbackimg[] = $this->feedback_image($this->is_right($ans)); 00118 $class .= ' ' . $this->feedback_class($this->is_right($ans)); 00119 } else { 00120 $feedbackimg[] = ''; 00121 } 00122 $classes[] = $class; 00123 } 00124 00125 $result = ''; 00126 $result .= html_writer::tag('div', $question->format_questiontext($qa), 00127 array('class' => 'qtext')); 00128 00129 $result .= html_writer::start_tag('div', array('class' => 'ablock')); 00130 $result .= html_writer::tag('div', $this->prompt(), array('class' => 'prompt')); 00131 00132 $result .= html_writer::start_tag('div', array('class' => 'answer')); 00133 foreach ($radiobuttons as $key => $radio) { 00134 $result .= html_writer::tag('div', $radio . ' ' . $feedbackimg[$key] . $feedback[$key], 00135 array('class' => $classes[$key])) . "\n"; 00136 } 00137 $result .= html_writer::end_tag('div'); // answer 00138 00139 $result .= html_writer::end_tag('div'); // ablock 00140 00141 if ($qa->get_state() == question_state::$invalid) { 00142 $result .= html_writer::nonempty_tag('div', 00143 $question->get_validation_error($qa->get_last_qt_data()), 00144 array('class' => 'validationerror')); 00145 } 00146 00147 return $result; 00148 } 00149 00150 protected function number_html($qnum) { 00151 return $qnum . '. '; 00152 } 00153 00160 protected function number_in_style($num, $style) { 00161 switch($style) { 00162 case 'abc': 00163 $number = chr(ord('a') + $num); 00164 break; 00165 case 'ABCD': 00166 $number = chr(ord('A') + $num); 00167 break; 00168 case '123': 00169 $number = $num + 1; 00170 break; 00171 case 'iii': 00172 $number = question_utils::int_to_roman($num + 1); 00173 break; 00174 case 'IIII': 00175 $number = strtoupper(question_utils::int_to_roman($num + 1)); 00176 break; 00177 case 'none': 00178 return ''; 00179 default: 00180 return 'ERR'; 00181 } 00182 return $this->number_html($number); 00183 } 00184 00185 public function specific_feedback(question_attempt $qa) { 00186 return $this->combined_feedback($qa); 00187 } 00188 } 00189 00190 00198 class qtype_multichoice_single_renderer extends qtype_multichoice_renderer_base { 00199 protected function get_input_type() { 00200 return 'radio'; 00201 } 00202 00203 protected function get_input_name(question_attempt $qa, $value) { 00204 return $qa->get_qt_field_name('answer'); 00205 } 00206 00207 protected function get_input_value($value) { 00208 return $value; 00209 } 00210 00211 protected function get_input_id(question_attempt $qa, $value) { 00212 return $qa->get_qt_field_name('answer' . $value); 00213 } 00214 00215 protected function is_right(question_answer $ans) { 00216 return $ans->fraction; 00217 } 00218 00219 protected function prompt() { 00220 return get_string('selectone', 'qtype_multichoice'); 00221 } 00222 00223 public function correct_response(question_attempt $qa) { 00224 $question = $qa->get_question(); 00225 00226 foreach ($question->answers as $ansid => $ans) { 00227 if (question_state::graded_state_for_fraction($ans->fraction) == 00228 question_state::$gradedright) { 00229 return get_string('correctansweris', 'qtype_multichoice', 00230 $question->format_text($ans->answer, $ans->answerformat, 00231 $qa, 'question', 'answer', $ansid)); 00232 } 00233 } 00234 00235 return ''; 00236 } 00237 } 00238 00246 class qtype_multichoice_multi_renderer extends qtype_multichoice_renderer_base { 00247 protected function get_input_type() { 00248 return 'checkbox'; 00249 } 00250 00251 protected function get_input_name(question_attempt $qa, $value) { 00252 return $qa->get_qt_field_name('choice' . $value); 00253 } 00254 00255 protected function get_input_value($value) { 00256 return 1; 00257 } 00258 00259 protected function get_input_id(question_attempt $qa, $value) { 00260 return $this->get_input_name($qa, $value); 00261 } 00262 00263 protected function is_right(question_answer $ans) { 00264 if ($ans->fraction > 0) { 00265 return 1; 00266 } else { 00267 return 0; 00268 } 00269 } 00270 00271 protected function prompt() { 00272 return get_string('selectmulti', 'qtype_multichoice'); 00273 } 00274 00275 public function correct_response(question_attempt $qa) { 00276 $question = $qa->get_question(); 00277 00278 $right = array(); 00279 foreach ($question->answers as $ansid => $ans) { 00280 if ($ans->fraction > 0) { 00281 $right[] = $question->format_text($ans->answer, $ans->answerformat, 00282 $qa, 'question', 'answer', $ansid); 00283 } 00284 } 00285 00286 if (!empty($right)) { 00287 return get_string('correctansweris', 'qtype_multichoice', 00288 implode(', ', $right)); 00289 } 00290 return ''; 00291 } 00292 00293 protected function num_parts_correct(question_attempt $qa) { 00294 if ($qa->get_question()->get_num_selected_choices($qa->get_last_qt_data()) > 00295 $qa->get_question()->get_num_correct_choices()) { 00296 return get_string('toomanyselected', 'qtype_multichoice'); 00297 } 00298 00299 return parent::num_parts_correct($qa); 00300 } 00301 }