Commit | Line | Data |
---|---|---|
d1b7e03d | 1 | <?php |
d1b7e03d TH |
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 | ||
d1b7e03d TH |
17 | /** |
18 | * Defines the renderer base class for question behaviours. | |
19 | * | |
017bc1d9 | 20 | * @package moodlecore |
d1b7e03d | 21 | * @subpackage questionbehaviours |
017bc1d9 TH |
22 | * @copyright 2009 The Open University |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
d1b7e03d TH |
24 | */ |
25 | ||
26 | ||
a17b297d TH |
27 | defined('MOODLE_INTERNAL') || die(); |
28 | ||
29 | ||
d1b7e03d TH |
30 | /** |
31 | * Renderer base class for question behaviours. | |
32 | * | |
33 | * The methods in this class are mostly called from {@link core_question_renderer} | |
34 | * which coordinates the overall output of questions. | |
35 | * | |
017bc1d9 TH |
36 | * @copyright 2009 The Open University |
37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
d1b7e03d | 38 | */ |
2b7da645 | 39 | abstract class qbehaviour_renderer extends plugin_renderer_base { |
d1b7e03d TH |
40 | /** |
41 | * Generate some HTML (which may be blank) that appears in the question | |
42 | * formulation area, afer the question type generated output. | |
43 | * | |
44 | * For example. | |
45 | * immediatefeedback and interactive mode use this to show the Submit button, | |
46 | * and CBM use this to display the certainty choices. | |
47 | * | |
48 | * @param question_attempt $qa a question attempt. | |
49 | * @param question_display_options $options controls what should and should not be displayed. | |
50 | * @return string HTML fragment. | |
51 | */ | |
52 | public function controls(question_attempt $qa, question_display_options $options) { | |
53 | return ''; | |
54 | } | |
55 | ||
56 | /** | |
57 | * Generate some HTML (which may be blank) that appears in the outcome area, | |
58 | * after the question-type generated output. | |
59 | * | |
60 | * For example, the CBM models use this to display an explanation of the score | |
61 | * adjustment that was made based on the certainty selected. | |
62 | * | |
63 | * @param question_attempt $qa a question attempt. | |
64 | * @param question_display_options $options controls what should and should not be displayed. | |
65 | * @return string HTML fragment. | |
66 | */ | |
67 | public function feedback(question_attempt $qa, question_display_options $options) { | |
68 | return ''; | |
69 | } | |
70 | ||
71 | public function manual_comment_fields(question_attempt $qa, question_display_options $options) { | |
f3d9872a AH |
72 | global $CFG; |
73 | ||
74 | require_once($CFG->dirroot.'/lib/filelib.php'); | |
75 | require_once($CFG->dirroot.'/repository/lib.php'); | |
76 | ||
2d682972 TH |
77 | $inputname = $qa->get_behaviour_field_name('comment'); |
78 | $id = $inputname . '_id'; | |
f3d9872a | 79 | list($commenttext, $commentformat, $commentstep) = $qa->get_current_manual_comment(); |
d1b7e03d | 80 | |
2d682972 TH |
81 | $editor = editors_get_preferred_editor($commentformat); |
82 | $strformats = format_text_menu(); | |
83 | $formats = $editor->get_supported_formats(); | |
84 | foreach ($formats as $fid) { | |
85 | $formats[$fid] = $strformats[$fid]; | |
86 | } | |
87 | ||
f3d9872a AH |
88 | $draftitemareainputname = $qa->get_behaviour_field_name('comment:itemid'); |
89 | $draftitemid = optional_param($draftitemareainputname, false, PARAM_INT); | |
90 | ||
91 | if (!$draftitemid && $commentstep === null) { | |
92 | $commenttext = ''; | |
93 | $draftitemid = file_get_unused_draft_itemid(); | |
94 | } else if (!$draftitemid) { | |
95 | list($draftitemid, $commenttext) = $commentstep->prepare_response_files_draft_itemid_with_text( | |
96 | 'bf_comment', $options->context->id, $commenttext); | |
97 | } | |
98 | ||
988592c5 | 99 | $editor->set_text($commenttext); |
f3d9872a AH |
100 | $editor->use_editor($id, question_utils::get_editor_options($options->context), |
101 | question_utils::get_filepicker_options($options->context, $draftitemid)); | |
2d682972 TH |
102 | |
103 | $commenteditor = html_writer::tag('div', html_writer::tag('textarea', s($commenttext), | |
104 | array('id' => $id, 'name' => $inputname, 'rows' => 10, 'cols' => 60))); | |
105 | ||
f3d9872a AH |
106 | $attributes = ['type' => 'hidden', 'name' => $draftitemareainputname, 'value' => $draftitemid]; |
107 | $commenteditor .= html_writer::empty_tag('input', $attributes); | |
108 | ||
c3cdf1e4 | 109 | $editorformat = ''; |
83690170 | 110 | if (count($formats) == 1) { |
2d682972 | 111 | reset($formats); |
c3cdf1e4 | 112 | $editorformat .= html_writer::empty_tag('input', array('type' => 'hidden', |
2d682972 | 113 | 'name' => $inputname . 'format', 'value' => key($formats))); |
2d682972 | 114 | } else { |
c3cdf1e4 FM |
115 | $editorformat = html_writer::start_tag('div', array('class' => 'fitem')); |
116 | $editorformat .= html_writer::start_tag('div', array('class' => 'fitemtitle')); | |
117 | $editorformat .= html_writer::tag('label', get_string('format'), array('for'=>'menu'.$inputname.'format')); | |
118 | $editorformat .= html_writer::end_tag('div'); | |
119 | $editorformat .= html_writer::start_tag('div', array('class' => 'felement fhtmleditor')); | |
120 | $editorformat .= html_writer::select($formats, $inputname.'format', $commentformat, ''); | |
121 | $editorformat .= html_writer::end_tag('div'); | |
122 | $editorformat .= html_writer::end_tag('div'); | |
2d682972 | 123 | } |
d1b7e03d | 124 | |
d1b7e03d | 125 | $comment = html_writer::tag('div', html_writer::tag('div', |
1631ceea | 126 | html_writer::tag('label', get_string('comment', 'question'), |
2d682972 | 127 | array('for' => $id)), array('class' => 'fitemtitle')) . |
f3d9872a | 128 | html_writer::tag('div', $commenteditor, array('class' => 'felement fhtmleditor', 'data-fieldtype' => "editor")), |
d1b7e03d | 129 | array('class' => 'fitem')); |
c3cdf1e4 | 130 | $comment .= $editorformat; |
d1b7e03d TH |
131 | |
132 | $mark = ''; | |
133 | if ($qa->get_max_mark()) { | |
134 | $currentmark = $qa->get_current_manual_mark(); | |
135 | $maxmark = $qa->get_max_mark(); | |
136 | ||
137 | $fieldsize = strlen($qa->format_max_mark($options->markdp)) - 1; | |
138 | $markfield = $qa->get_behaviour_field_name('mark'); | |
139 | ||
140 | $attributes = array( | |
141 | 'type' => 'text', | |
142 | 'size' => $fieldsize, | |
143 | 'name' => $markfield, | |
c3cdf1e4 | 144 | 'id'=> $markfield |
d1b7e03d TH |
145 | ); |
146 | if (!is_null($currentmark)) { | |
b2694c02 | 147 | $attributes['value'] = $currentmark; |
d1b7e03d | 148 | } |
d1b7e03d TH |
149 | |
150 | $markrange = html_writer::empty_tag('input', array( | |
151 | 'type' => 'hidden', | |
152 | 'name' => $qa->get_behaviour_field_name('maxmark'), | |
153 | 'value' => $maxmark, | |
154 | )) . html_writer::empty_tag('input', array( | |
155 | 'type' => 'hidden', | |
156 | 'name' => $qa->get_control_field_name('minfraction'), | |
157 | 'value' => $qa->get_min_fraction(), | |
4e3d8293 TH |
158 | )) . html_writer::empty_tag('input', array( |
159 | 'type' => 'hidden', | |
160 | 'name' => $qa->get_control_field_name('maxfraction'), | |
161 | 'value' => $qa->get_max_fraction(), | |
d1b7e03d TH |
162 | )); |
163 | ||
b2694c02 | 164 | $error = $qa->validate_manual_mark($currentmark); |
d1b7e03d | 165 | $errorclass = ''; |
b2694c02 TH |
166 | if ($error !== '') { |
167 | $erroclass = ' error'; | |
168 | $error = html_writer::tag('span', $error, | |
d1b7e03d TH |
169 | array('class' => 'error')) . html_writer::empty_tag('br'); |
170 | } | |
171 | ||
284c795d TH |
172 | $a = new stdClass(); |
173 | $a->max = $qa->format_max_mark($options->markdp); | |
174 | $a->mark = html_writer::empty_tag('input', $attributes); | |
d1b7e03d | 175 | $mark = html_writer::tag('div', html_writer::tag('div', |
1631ceea TH |
176 | html_writer::tag('label', get_string('mark', 'question'), |
177 | array('for' => $markfield)), | |
d1b7e03d TH |
178 | array('class' => 'fitemtitle')) . |
179 | html_writer::tag('div', $error . get_string('xoutofmax', 'question', $a) . | |
180 | $markrange, array('class' => 'felement ftext' . $errorclass) | |
181 | ), array('class' => 'fitem')); | |
d1b7e03d TH |
182 | } |
183 | ||
184 | return html_writer::tag('fieldset', html_writer::tag('div', $comment . $mark, | |
185 | array('class' => 'fcontainer clearfix')), array('class' => 'hidden')); | |
186 | } | |
187 | ||
188 | public function manual_comment_view(question_attempt $qa, question_display_options $options) { | |
189 | $output = ''; | |
190 | if ($qa->has_manual_comment()) { | |
64207dab TH |
191 | $output .= get_string('commentx', 'question', |
192 | $qa->get_behaviour(false)->format_comment(null, null, $options->context)); | |
d1b7e03d TH |
193 | } |
194 | if ($options->manualcommentlink) { | |
7ee80cab TH |
195 | $url = new moodle_url($options->manualcommentlink, array('slot' => $qa->get_slot())); |
196 | $link = $this->output->action_link($url, get_string('commentormark', 'question'), | |
1631ceea TH |
197 | new popup_action('click', $url, 'commentquestion', |
198 | array('width' => 600, 'height' => 800))); | |
d1b7e03d TH |
199 | $output .= html_writer::tag('div', $link, array('class' => 'commentlink')); |
200 | } | |
201 | return $output; | |
202 | } | |
203 | ||
204 | /** | |
205 | * Display the manual comment, and a link to edit it, if appropriate. | |
206 | * | |
207 | * @param question_attempt $qa a question attempt. | |
208 | * @param question_display_options $options controls what should and should not be displayed. | |
209 | * @return string HTML fragment. | |
210 | */ | |
211 | public function manual_comment(question_attempt $qa, question_display_options $options) { | |
212 | if ($options->manualcomment == question_display_options::EDITABLE) { | |
213 | return $this->manual_comment_fields($qa, $options); | |
214 | ||
215 | } else if ($options->manualcomment == question_display_options::VISIBLE) { | |
216 | return $this->manual_comment_view($qa, $options); | |
217 | ||
218 | } else { | |
219 | return ''; | |
220 | } | |
221 | } | |
222 | ||
223 | /** | |
224 | * Several behaviours need a submit button, so put the common code here. | |
225 | * The button is disabled if the question is displayed read-only. | |
226 | * @param question_display_options $options controls what should and should not be displayed. | |
227 | * @return string HTML fragment. | |
228 | */ | |
229 | protected function submit_button(question_attempt $qa, question_display_options $options) { | |
81e47a35 TH |
230 | if (!$qa->get_state()->is_active()) { |
231 | return ''; | |
232 | } | |
d1b7e03d TH |
233 | $attributes = array( |
234 | 'type' => 'submit', | |
235 | 'id' => $qa->get_behaviour_field_name('submit'), | |
236 | 'name' => $qa->get_behaviour_field_name('submit'), | |
237 | 'value' => get_string('check', 'question'), | |
29551c4b | 238 | 'class' => 'submit btn btn-secondary', |
d1b7e03d TH |
239 | ); |
240 | if ($options->readonly) { | |
241 | $attributes['disabled'] = 'disabled'; | |
242 | } | |
243 | $output = html_writer::empty_tag('input', $attributes); | |
244 | if (!$options->readonly) { | |
cce1b655 | 245 | $this->page->requires->js_init_call('M.core_question_engine.init_submit_button', |
579da44a | 246 | array($attributes['id'])); |
d1b7e03d TH |
247 | } |
248 | return $output; | |
249 | } | |
250 | ||
251 | /** | |
252 | * Return any HTML that needs to be included in the page's <head> when | |
253 | * questions using this model are used. | |
254 | * @param $qa the question attempt that will be displayed on the page. | |
255 | * @return string HTML fragment. | |
256 | */ | |
257 | public function head_code(question_attempt $qa) { | |
258 | return ''; | |
259 | } | |
02d3e4d5 TH |
260 | |
261 | /** | |
262 | * Generate the display of the marks for this question. | |
263 | * @param question_attempt $qa the question attempt to display. | |
264 | * @param core_question_renderer $qoutput the renderer for standard parts of questions. | |
265 | * @param question_display_options $options controls what should and should not be displayed. | |
266 | * @return HTML fragment. | |
267 | */ | |
268 | public function mark_summary(question_attempt $qa, core_question_renderer $qoutput, | |
269 | question_display_options $options) { | |
270 | return $qoutput->standard_mark_summary($qa, $this, $options); | |
271 | } | |
272 | ||
273 | /** | |
274 | * Generate the display of the available marks for this question. | |
275 | * @param question_attempt $qa the question attempt to display. | |
276 | * @param core_question_renderer $qoutput the renderer for standard parts of questions. | |
277 | * @param question_display_options $options controls what should and should not be displayed. | |
278 | * @return HTML fragment. | |
279 | */ | |
280 | public function marked_out_of_max(question_attempt $qa, core_question_renderer $qoutput, | |
281 | question_display_options $options) { | |
282 | return $qoutput->standard_marked_out_of_max($qa, $options); | |
283 | } | |
284 | ||
285 | /** | |
286 | * Generate the display of the marks for this question out of the available marks. | |
287 | * @param question_attempt $qa the question attempt to display. | |
288 | * @param core_question_renderer $qoutput the renderer for standard parts of questions. | |
289 | * @param question_display_options $options controls what should and should not be displayed. | |
290 | * @return HTML fragment. | |
291 | */ | |
292 | public function mark_out_of_max(question_attempt $qa, core_question_renderer $qoutput, | |
293 | question_display_options $options) { | |
294 | return $qoutput->standard_mark_out_of_max($qa, $options); | |
295 | } | |
d1b7e03d | 296 | } |