forked from moodle/moodle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrendererbase.php
265 lines (236 loc) · 9.64 KB
/
rendererbase.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Defines the renderer base classes for question types.
*
* @package moodlecore
* @subpackage questiontypes
* @copyright 2009 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Renderer base classes for question types.
*
* @copyright 2009 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class qtype_renderer extends plugin_renderer_base {
/**
* Generate the display of the formulation part of the question. This is the
* area that contains the quetsion text, and the controls for students to
* input their answers. Some question types also embed bits of feedback, for
* example ticks and crosses, in this area.
*
* @param question_attempt $qa the question attempt to display.
* @param question_display_options $options controls what should and should not be displayed.
* @return string HTML fragment.
*/
public function formulation_and_controls(question_attempt $qa,
question_display_options $options) {
return $qa->get_question()->format_questiontext($qa);
}
/**
* In the question output there are some class="accesshide" headers to help
* screen-readers. This method returns the text to use for the heading above
* the formulation_and_controls section.
* @return string to use as the heading.
*/
public function formulation_heading() {
return get_string('questiontext', 'question');
}
/**
* Output hidden form fields to clear any wrong parts of the student's response.
*
* This method will only be called if the question is in read-only mode.
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
*/
public function clear_wrong(question_attempt $qa) {
$response = $qa->get_last_qt_data();
if (!$response) {
return '';
}
$cleanresponse = $qa->get_question()->clear_wrong_from_response($response);
$output = '';
foreach ($cleanresponse as $name => $value) {
$attr = array(
'type' => 'hidden',
'name' => $qa->get_qt_field_name($name),
'value' => s($value),
);
$output .= html_writer::empty_tag('input', $attr);
}
return $output;
}
/**
* Generate the display of the outcome part of the question. This is the
* area that contains the various forms of feedback. This function generates
* the content of this area belonging to the question type.
*
* Subclasses will normally want to override the more specific methods
* {specific_feedback()}, {general_feedback()} and {correct_response()}
* that this method calls.
*
* @param question_attempt $qa the question attempt to display.
* @param question_display_options $options controls what should and should not be displayed.
* @return string HTML fragment.
*/
public function feedback(question_attempt $qa, question_display_options $options) {
$output = '';
$hint = null;
if ($options->feedback) {
$output .= html_writer::nonempty_tag('div', $this->specific_feedback($qa),
array('class' => 'specificfeedback'));
$hint = $qa->get_applicable_hint();
}
if ($options->numpartscorrect) {
$output .= html_writer::nonempty_tag('div', $this->num_parts_correct($qa),
array('class' => 'numpartscorrect'));
}
if ($hint) {
$output .= $this->hint($qa, $hint);
}
if ($options->generalfeedback) {
$output .= html_writer::nonempty_tag('div', $this->general_feedback($qa),
array('class' => 'generalfeedback'));
}
if ($options->rightanswer) {
$output .= html_writer::nonempty_tag('div', $this->correct_response($qa),
array('class' => 'rightanswer'));
}
return $output;
}
/**
* Generate the specific feedback. This is feedback that varies according to
* the response the student gave.
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
*/
protected function specific_feedback(question_attempt $qa) {
return '';
}
/**
* Gereate a brief statement of how many sub-parts of this question the
* student got right.
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
*/
protected function num_parts_correct(question_attempt $qa) {
$a = new stdClass();
list($a->num, $a->outof) = $qa->get_question()->get_num_parts_right(
$qa->get_last_qt_data());
if (is_null($a->outof)) {
return '';
} else {
return get_string('yougotnright', 'question', $a);
}
}
/**
* Gereate the specific feedback. This is feedback that varies according to
* the response the student gave.
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
*/
protected function hint(question_attempt $qa, question_hint $hint) {
return html_writer::nonempty_tag('div',
$qa->get_question()->format_hint($hint, $qa), array('class' => 'hint'));
}
/**
* Gereate the general feedback. This is feedback is shown ot all students.
*
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
*/
protected function general_feedback(question_attempt $qa) {
return $qa->get_question()->format_generalfeedback($qa);
}
/**
* Gereate an automatic description of the correct response to this question.
* Not all question types can do this. If it is not possible, this method
* should just return an empty string.
*
* @param question_attempt $qa the question attempt to display.
* @return string HTML fragment.
*/
protected function correct_response(question_attempt $qa) {
return '';
}
/**
* Display any extra question-type specific content that should be visible
* when grading, if appropriate.
*
* @param question_attempt $qa a question attempt.
* @param question_display_options $options controls what should and should not be displayed.
* @return string HTML fragment.
*/
public function manual_comment(question_attempt $qa, question_display_options $options) {
return '';
}
/**
* Return any HTML that needs to be included in the page's <head> when this
* question is used.
* @param $qa the question attempt that will be displayed on the page.
* @return string HTML fragment.
*/
public function head_code(question_attempt $qa) {
// This method is used by the Opaque question type. The remote question
// engine can send back arbitrary CSS that we have to link to in the
// page header. If it was not for that, we might be able to eliminate
// this method and load the required CSS and JS some other way.
$qa->get_question()->qtype->find_standard_scripts();
}
protected function feedback_class($fraction) {
return question_state::graded_state_for_fraction($fraction)->get_feedback_class();
}
/**
* Return an appropriate icon (green tick, red cross, etc.) for a grade.
* @param float $fraction grade on a scale 0..1.
* @param bool $selected whether to show a big or small icon. (Deprecated)
* @return string html fragment.
*/
protected function feedback_image($fraction, $selected = true) {
$feedbackclass = question_state::graded_state_for_fraction($fraction)->get_feedback_class();
return $this->output->pix_icon('i/grade_' . $feedbackclass, get_string($feedbackclass, 'question'));
}
}
/**
* Renderer base classes for question types.
*
* @copyright 2010 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class qtype_with_combined_feedback_renderer extends qtype_renderer {
protected function combined_feedback(question_attempt $qa) {
$question = $qa->get_question();
$state = $qa->get_state();
if (!$state->is_finished()) {
$response = $qa->get_last_qt_data();
if (!$qa->get_question()->is_gradable_response($response)) {
return '';
}
list($notused, $state) = $qa->get_question()->grade_response($response);
}
$feedback = '';
$field = $state->get_feedback_class() . 'feedback';
$format = $state->get_feedback_class() . 'feedbackformat';
if ($question->$field) {
$feedback .= $question->format_text($question->$field, $question->$format,
$qa, 'question', $field, $question->id);
}
return $feedback;
}
}