weekly release 3.1dev
[moodle.git] / grade / grading / form / rubric / renderer.php
CommitLineData
c586d2bf 1<?php
c586d2bf
MG
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/**
d22e9e32
MG
18 * Contains renderer used for displaying rubric
19 *
20 * @package gradingform_rubric
c586d2bf
MG
21 * @copyright 2011 Marina Glancy
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
c586d2bf
MG
25defined('MOODLE_INTERNAL') || die();
26
27/**
28 * Grading method plugin renderer
d22e9e32 29 *
5dc1ca87 30 * @package gradingform_rubric
d22e9e32
MG
31 * @copyright 2011 Marina Glancy
32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
c586d2bf 33 */
2ae7faf1 34class gradingform_rubric_renderer extends plugin_renderer_base {
c586d2bf 35
ab156741 36 /**
fc5adc3b
MG
37 * This function returns html code for displaying criterion. Depending on $mode it may be the
38 * code to edit rubric, to preview the rubric, to evaluate somebody or to review the evaluation.
39 *
40 * This function may be called from display_rubric() to display the whole rubric, or it can be
41 * called by itself to return a template used by JavaScript to add new empty criteria to the
42 * rubric being designed.
43 * In this case it will use macros like {NAME}, {LEVELS}, {CRITERION-id}, etc.
44 *
45 * When overriding this function it is very important to remember that all elements of html
46 * form (in edit or evaluate mode) must have the name $elementname.
ab156741 47 *
fc5adc3b
MG
48 * Also JavaScript relies on the class names of elements and when developer changes them
49 * script might stop working.
50 *
d22e9e32
MG
51 * @param int $mode rubric display mode, see {@link gradingform_rubric_controller}
52 * @param array $options display options for this rubric, defaults are: {@link gradingform_rubric_controller::get_default_options()}
fc5adc3b
MG
53 * @param string $elementname the name of the form element (in editor mode) or the prefix for div ids (in view mode)
54 * @param array|null $criterion criterion data
3c2b3cb3 55 * @param string $levelsstr evaluated templates for this criterion levels
fc5adc3b 56 * @param array|null $value (only in view mode) teacher's feedback on this criterion
ab156741
MG
57 * @return string
58 */
3c2b3cb3 59 public function criterion_template($mode, $options, $elementname = '{NAME}', $criterion = null, $levelsstr = '{LEVELS}', $value = null) {
d22e9e32 60 // TODO MDL-31235 description format, remark format
ab156741
MG
61 if ($criterion === null || !is_array($criterion) || !array_key_exists('id', $criterion)) {
62 $criterion = array('id' => '{CRITERION-id}', 'description' => '{CRITERION-description}', 'sortorder' => '{CRITERION-sortorder}', 'class' => '{CRITERION-class}');
63 } else {
64 foreach (array('sortorder', 'description', 'class') as $key) {
65 // set missing array elements to empty strings to avoid warnings
66 if (!array_key_exists($key, $criterion)) {
67 $criterion[$key] = '';
68 }
69 }
70 }
3c2b3cb3 71 $criteriontemplate = html_writer::start_tag('tr', array('class' => 'criterion'. $criterion['class'], 'id' => '{NAME}-criteria-{CRITERION-id}'));
ab156741 72 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
3c2b3cb3 73 $criteriontemplate .= html_writer::start_tag('td', array('class' => 'controls'));
e22c8d2a 74 foreach (array('moveup', 'delete', 'movedown', 'duplicate') as $key) {
ab156741 75 $value = get_string('criterion'.$key, 'gradingform_rubric');
39c6f4b6 76 $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}]['.$key.']',
4f110c47 77 'id' => '{NAME}-criteria-{CRITERION-id}-'.$key, 'value' => $value, 'title' => $value, 'tabindex' => -1));
3c2b3cb3 78 $criteriontemplate .= html_writer::tag('div', $button, array('class' => $key));
ab156741 79 }
3c2b3cb3
MG
80 $criteriontemplate .= html_writer::end_tag('td'); // .controls
81 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
b9b2968e 82 $description = html_writer::tag('textarea', s($criterion['description']), array('name' => '{NAME}[criteria][{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5'));
ab156741
MG
83 } else {
84 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) {
3c2b3cb3
MG
85 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder']));
86 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][description]', 'value' => $criterion['description']));
ab156741 87 }
b9b2968e 88 $description = s($criterion['description']);
ab156741 89 }
2ae7faf1
MG
90 $descriptionclass = 'description';
91 if (isset($criterion['error_description'])) {
92 $descriptionclass .= ' error';
93 }
3c2b3cb3
MG
94 $criteriontemplate .= html_writer::tag('td', $description, array('class' => $descriptionclass, 'id' => '{NAME}-criteria-{CRITERION-id}-description'));
95 $levelsstrtable = html_writer::tag('table', html_writer::tag('tr', $levelsstr, array('id' => '{NAME}-criteria-{CRITERION-id}-levels')));
2ae7faf1
MG
96 $levelsclass = 'levels';
97 if (isset($criterion['error_levels'])) {
98 $levelsclass .= ' error';
99 }
3c2b3cb3 100 $criteriontemplate .= html_writer::tag('td', $levelsstrtable, array('class' => $levelsclass));
ab156741
MG
101 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
102 $value = get_string('criterionaddlevel', 'gradingform_rubric');
39c6f4b6
MG
103 $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][addlevel]',
104 'id' => '{NAME}-criteria-{CRITERION-id}-levels-addlevel', 'value' => $value, 'title' => $value));
3c2b3cb3 105 $criteriontemplate .= html_writer::tag('td', $button, array('class' => 'addlevel'));
ab156741 106 }
39c6f4b6
MG
107 $displayremark = ($options['enableremarks'] && ($mode != gradingform_rubric_controller::DISPLAY_VIEW || $options['showremarksstudent']));
108 if ($displayremark) {
5060997b 109 $currentremark = '';
39c6f4b6
MG
110 if (isset($value['remark'])) {
111 $currentremark = $value['remark'];
112 }
113 if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
b9b2968e 114 $input = html_writer::tag('textarea', s($currentremark), array('name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'cols' => '10', 'rows' => '5'));
3c2b3cb3 115 $criteriontemplate .= html_writer::tag('td', $input, array('class' => 'remark'));
39c6f4b6 116 } else if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN) {
3c2b3cb3 117 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'value' => $currentremark));
39c6f4b6 118 }else if ($mode == gradingform_rubric_controller::DISPLAY_REVIEW || $mode == gradingform_rubric_controller::DISPLAY_VIEW) {
b9b2968e 119 $criteriontemplate .= html_writer::tag('td', s($currentremark), array('class' => 'remark'));
39c6f4b6 120 }
5060997b 121 }
3c2b3cb3 122 $criteriontemplate .= html_writer::end_tag('tr'); // .criterion
ab156741 123
3c2b3cb3
MG
124 $criteriontemplate = str_replace('{NAME}', $elementname, $criteriontemplate);
125 $criteriontemplate = str_replace('{CRITERION-id}', $criterion['id'], $criteriontemplate);
126 return $criteriontemplate;
ab156741
MG
127 }
128
fc5adc3b
MG
129 /**
130 * This function returns html code for displaying one level of one criterion. Depending on $mode
131 * it may be the code to edit rubric, to preview the rubric, to evaluate somebody or to review the evaluation.
132 *
133 * This function may be called from display_rubric() to display the whole rubric, or it can be
134 * called by itself to return a template used by JavaScript to add new empty level to the
135 * criterion during the design of rubric.
136 * In this case it will use macros like {NAME}, {CRITERION-id}, {LEVEL-id}, etc.
137 *
138 * When overriding this function it is very important to remember that all elements of html
139 * form (in edit or evaluate mode) must have the name $elementname.
140 *
141 * Also JavaScript relies on the class names of elements and when developer changes them
142 * script might stop working.
143 *
d22e9e32
MG
144 * @param int $mode rubric display mode see {@link gradingform_rubric_controller}
145 * @param array $options display options for this rubric, defaults are: {@link gradingform_rubric_controller::get_default_options()}
fc5adc3b
MG
146 * @param string $elementname the name of the form element (in editor mode) or the prefix for div ids (in view mode)
147 * @param string|int $criterionid either id of the nesting criterion or a macro for template
148 * @param array|null $level level data, also in view mode it might also have property $level['checked'] whether this level is checked
149 * @return string
150 */
39c6f4b6 151 public function level_template($mode, $options, $elementname = '{NAME}', $criterionid = '{CRITERION-id}', $level = null) {
d22e9e32 152 // TODO MDL-31235 definition format
5060997b 153 if (!isset($level['id'])) {
ab156741
MG
154 $level = array('id' => '{LEVEL-id}', 'definition' => '{LEVEL-definition}', 'score' => '{LEVEL-score}', 'class' => '{LEVEL-class}', 'checked' => false);
155 } else {
156 foreach (array('score', 'definition', 'class', 'checked') as $key) {
157 // set missing array elements to empty strings to avoid warnings
158 if (!array_key_exists($key, $level)) {
159 $level[$key] = '';
160 }
161 }
162 }
163
164 // Template for one level within one criterion
39c6f4b6
MG
165 $tdattributes = array('id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}', 'class' => 'level'. $level['class']);
166 if (isset($level['tdwidth'])) {
167 $tdattributes['width'] = round($level['tdwidth']).'%';
168 }
3c2b3cb3
MG
169 $leveltemplate = html_writer::start_tag('td', $tdattributes);
170 $leveltemplate .= html_writer::start_tag('div', array('class' => 'level-wrapper'));
ab156741 171 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
b9b2968e 172 $definition = html_writer::tag('textarea', s($level['definition']), array('name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4'));
29bea634
RW
173 $score = html_writer::label(get_string('criterionempty', 'gradingform_rubric'), '{NAME}criteria{CRITERION-id}levels{LEVEL-id}', false, array('class' => 'accesshide'));
174 $score .= html_writer::empty_tag('input', array('type' => 'text','id' => '{NAME}criteria{CRITERION-id}levels{LEVEL-id}', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][score]', 'size' => '3', 'value' => $level['score']));
ab156741
MG
175 } else {
176 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) {
3c2b3cb3
MG
177 $leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'value' => $level['definition']));
178 $leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][score]', 'value' => $level['score']));
ab156741 179 }
b9b2968e 180 $definition = s($level['definition']);
ab156741
MG
181 $score = $level['score'];
182 }
183 if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) {
5060997b 184 $input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => '{NAME}[criteria][{CRITERION-id}][levelid]', 'value' => $level['id']) +
ab156741 185 ($level['checked'] ? array('checked' => 'checked') : array()));
3c2b3cb3 186 $leveltemplate .= html_writer::tag('div', $input, array('class' => 'radio'));
ab156741
MG
187 }
188 if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN && $level['checked']) {
3c2b3cb3 189 $leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levelid]', 'value' => $level['id']));
ab156741 190 }
a19d1057 191 $score = html_writer::tag('span', $score, array('id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-score', 'class' => 'scorevalue'));
2ae7faf1
MG
192 $definitionclass = 'definition';
193 if (isset($level['error_definition'])) {
194 $definitionclass .= ' error';
195 }
3c2b3cb3 196 $leveltemplate .= html_writer::tag('div', $definition, array('class' => $definitionclass, 'id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-definition'));
39c6f4b6
MG
197 $displayscore = true;
198 if (!$options['showscoreteacher'] && in_array($mode, array(gradingform_rubric_controller::DISPLAY_EVAL, gradingform_rubric_controller::DISPLAY_EVAL_FROZEN, gradingform_rubric_controller::DISPLAY_REVIEW))) {
199 $displayscore = false;
200 }
577c8964 201 if (!$options['showscorestudent'] && in_array($mode, array(gradingform_rubric_controller::DISPLAY_VIEW, gradingform_rubric_controller::DISPLAY_PREVIEW_GRADED))) {
39c6f4b6
MG
202 $displayscore = false;
203 }
204 if ($displayscore) {
2ae7faf1
MG
205 $scoreclass = 'score';
206 if (isset($level['error_score'])) {
207 $scoreclass .= ' error';
208 }
3c2b3cb3 209 $leveltemplate .= html_writer::tag('div', get_string('scorepostfix', 'gradingform_rubric', $score), array('class' => $scoreclass));
39c6f4b6 210 }
ab156741
MG
211 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
212 $value = get_string('leveldelete', 'gradingform_rubric');
4f110c47 213 $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][delete]', 'id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-delete', 'value' => $value, 'title' => $value, 'tabindex' => -1));
3c2b3cb3 214 $leveltemplate .= html_writer::tag('div', $button, array('class' => 'delete'));
ab156741 215 }
3c2b3cb3
MG
216 $leveltemplate .= html_writer::end_tag('div'); // .level-wrapper
217 $leveltemplate .= html_writer::end_tag('td'); // .level
ab156741 218
3c2b3cb3
MG
219 $leveltemplate = str_replace('{NAME}', $elementname, $leveltemplate);
220 $leveltemplate = str_replace('{CRITERION-id}', $criterionid, $leveltemplate);
221 $leveltemplate = str_replace('{LEVEL-id}', $level['id'], $leveltemplate);
222 return $leveltemplate;
ab156741
MG
223 }
224
fc5adc3b
MG
225 /**
226 * This function returns html code for displaying rubric template (content before and after
227 * criteria list). Depending on $mode it may be the code to edit rubric, to preview the rubric,
228 * to evaluate somebody or to review the evaluation.
229 *
230 * This function is called from display_rubric() to display the whole rubric.
231 *
232 * When overriding this function it is very important to remember that all elements of html
233 * form (in edit or evaluate mode) must have the name $elementname.
234 *
235 * Also JavaScript relies on the class names of elements and when developer changes them
236 * script might stop working.
237 *
d22e9e32
MG
238 * @param int $mode rubric display mode see {@link gradingform_rubric_controller}
239 * @param array $options display options for this rubric, defaults are: {@link gradingform_rubric_controller::get_default_options()}
fc5adc3b 240 * @param string $elementname the name of the form element (in editor mode) or the prefix for div ids (in view mode)
3c2b3cb3 241 * @param string $criteriastr evaluated templates for this rubric's criteria
fc5adc3b
MG
242 * @return string
243 */
3c2b3cb3 244 protected function rubric_template($mode, $options, $elementname, $criteriastr) {
ab156741
MG
245 $classsuffix = ''; // CSS suffix for class of the main div. Depends on the mode
246 switch ($mode) {
247 case gradingform_rubric_controller::DISPLAY_EDIT_FULL:
248 $classsuffix = ' editor editable'; break;
249 case gradingform_rubric_controller::DISPLAY_EDIT_FROZEN:
250 $classsuffix = ' editor frozen'; break;
251 case gradingform_rubric_controller::DISPLAY_PREVIEW:
577c8964 252 case gradingform_rubric_controller::DISPLAY_PREVIEW_GRADED:
ab156741
MG
253 $classsuffix = ' editor preview'; break;
254 case gradingform_rubric_controller::DISPLAY_EVAL:
255 $classsuffix = ' evaluate editable'; break;
256 case gradingform_rubric_controller::DISPLAY_EVAL_FROZEN:
257 $classsuffix = ' evaluate frozen'; break;
258 case gradingform_rubric_controller::DISPLAY_REVIEW:
259 $classsuffix = ' review'; break;
39c6f4b6
MG
260 case gradingform_rubric_controller::DISPLAY_VIEW:
261 $classsuffix = ' view'; break;
ab156741
MG
262 }
263
3c2b3cb3
MG
264 $rubrictemplate = html_writer::start_tag('div', array('id' => 'rubric-{NAME}', 'class' => 'clearfix gradingform_rubric'.$classsuffix));
265 $rubrictemplate .= html_writer::tag('table', $criteriastr, array('class' => 'criteria', 'id' => '{NAME}-criteria'));
ab156741
MG
266 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
267 $value = get_string('addcriterion', 'gradingform_rubric');
39c6f4b6 268 $input = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][addcriterion]', 'id' => '{NAME}-criteria-addcriterion', 'value' => $value, 'title' => $value));
3c2b3cb3 269 $rubrictemplate .= html_writer::tag('div', $input, array('class' => 'addcriterion'));
ab156741 270 }
3c2b3cb3
MG
271 $rubrictemplate .= $this->rubric_edit_options($mode, $options);
272 $rubrictemplate .= html_writer::end_tag('div');
ab156741 273
3c2b3cb3 274 return str_replace('{NAME}', $elementname, $rubrictemplate);
ab156741
MG
275 }
276
3c2b3cb3
MG
277 /**
278 * Generates html template to view/edit the rubric options. Expression {NAME} is used in
279 * template for the form element name
280 *
d22e9e32
MG
281 * @param int $mode rubric display mode see {@link gradingform_rubric_controller}
282 * @param array $options display options for this rubric, defaults are: {@link gradingform_rubric_controller::get_default_options()}
3c2b3cb3
MG
283 * @return string
284 */
39c6f4b6
MG
285 protected function rubric_edit_options($mode, $options) {
286 if ($mode != gradingform_rubric_controller::DISPLAY_EDIT_FULL
287 && $mode != gradingform_rubric_controller::DISPLAY_EDIT_FROZEN
288 && $mode != gradingform_rubric_controller::DISPLAY_PREVIEW) {
577c8964 289 // Options are displayed only for people who can manage
39c6f4b6
MG
290 return;
291 }
292 $html = html_writer::start_tag('div', array('class' => 'options'));
293 $html .= html_writer::tag('div', get_string('rubricoptions', 'gradingform_rubric'), array('class' => 'optionsheading'));
294 $attrs = array('type' => 'hidden', 'name' => '{NAME}[options][optionsset]', 'value' => 1);
295 foreach ($options as $option => $value) {
296 $html .= html_writer::start_tag('div', array('class' => 'option '.$option));
297 $attrs = array('name' => '{NAME}[options]['.$option.']', 'id' => '{NAME}-options-'.$option);
298 switch ($option) {
299 case 'sortlevelsasc':
300 // Display option as dropdown
29bea634 301 $html .= html_writer::label(get_string($option, 'gradingform_rubric'), $attrs['id'], false, array('class' => 'label'));
39c6f4b6
MG
302 $value = (int)(!!$value); // make sure $value is either 0 or 1
303 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) {
304 $selectoptions = array(0 => get_string($option.'0', 'gradingform_rubric'), 1 => get_string($option.'1', 'gradingform_rubric'));
3c2b3cb3
MG
305 $valuestr = html_writer::select($selectoptions, $attrs['name'], $value, false, array('id' => $attrs['id']));
306 $html .= html_writer::tag('span', $valuestr, array('class' => 'value'));
39c6f4b6
MG
307 } else {
308 $html .= html_writer::tag('span', get_string($option.$value, 'gradingform_rubric'), array('class' => 'value'));
309 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) {
310 $html .= html_writer::empty_tag('input', $attrs + array('type' => 'hidden', 'value' => $value));
311 }
312 }
313 break;
314 default:
0136124e
MG
315 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN && $value) {
316 $html .= html_writer::empty_tag('input', $attrs + array('type' => 'hidden', 'value' => $value));
317 }
39c6f4b6
MG
318 // Display option as checkbox
319 $attrs['type'] = 'checkbox';
320 $attrs['value'] = 1;
321 if ($value) {
322 $attrs['checked'] = 'checked';
323 }
0136124e 324 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_PREVIEW) {
39c6f4b6
MG
325 $attrs['disabled'] = 'disabled';
326 unset($attrs['name']);
327 }
328 $html .= html_writer::empty_tag('input', $attrs);
329 $html .= html_writer::tag('label', get_string($option, 'gradingform_rubric'), array('for' => $attrs['id']));
330 break;
331 }
332 $html .= html_writer::end_tag('div'); // .option
333 }
334 $html .= html_writer::end_tag('div'); // .options
335 return $html;
336 }
337
ab156741 338 /**
fc5adc3b
MG
339 * This function returns html code for displaying rubric. Depending on $mode it may be the code
340 * to edit rubric, to preview the rubric, to evaluate somebody or to review the evaluation.
341 *
342 * It is very unlikely that this function needs to be overriden by theme. It does not produce
343 * any html code, it just prepares data about rubric design and evaluation, adds the CSS
344 * class to elements and calls the functions level_template, criterion_template and
345 * rubric_template
ab156741 346 *
fc5adc3b 347 * @param array $criteria data about the rubric design
d22e9e32
MG
348 * @param array $options display options for this rubric, defaults are: {@link gradingform_rubric_controller::get_default_options()}
349 * @param int $mode rubric display mode, see {@link gradingform_rubric_controller}
fc5adc3b
MG
350 * @param string $elementname the name of the form element (in editor mode) or the prefix for div ids (in view mode)
351 * @param array $values evaluation result
ab156741
MG
352 * @return string
353 */
39c6f4b6 354 public function display_rubric($criteria, $options, $mode, $elementname = null, $values = null) {
3c2b3cb3 355 $criteriastr = '';
ab156741
MG
356 $cnt = 0;
357 foreach ($criteria as $id => $criterion) {
358 $criterion['class'] = $this->get_css_class_suffix($cnt++, sizeof($criteria) -1);
39c6f4b6 359 $criterion['id'] = $id;
3c2b3cb3 360 $levelsstr = '';
ab156741 361 $levelcnt = 0;
5060997b
MG
362 if (isset($values['criteria'][$id])) {
363 $criterionvalue = $values['criteria'][$id];
364 } else {
365 $criterionvalue = null;
366 }
ab156741 367 foreach ($criterion['levels'] as $levelid => $level) {
39c6f4b6 368 $level['id'] = $levelid;
ab156741 369 $level['class'] = $this->get_css_class_suffix($levelcnt++, sizeof($criterion['levels']) -1);
5060997b 370 $level['checked'] = (isset($criterionvalue['levelid']) && ((int)$criterionvalue['levelid'] === $levelid));
39c6f4b6 371 if ($level['checked'] && ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_REVIEW || $mode == gradingform_rubric_controller::DISPLAY_VIEW)) {
ab156741 372 $level['class'] .= ' checked';
fc5adc3b 373 //in mode DISPLAY_EVAL the class 'checked' will be added by JS if it is enabled. If JS is not enabled, the 'checked' class will only confuse
ab156741 374 }
188e840b
MG
375 if (isset($criterionvalue['savedlevelid']) && ((int)$criterionvalue['savedlevelid'] === $levelid)) {
376 $level['class'] .= ' currentchecked';
377 }
39c6f4b6 378 $level['tdwidth'] = 100/count($criterion['levels']);
3c2b3cb3 379 $levelsstr .= $this->level_template($mode, $options, $elementname, $id, $level);
ab156741 380 }
3c2b3cb3 381 $criteriastr .= $this->criterion_template($mode, $options, $elementname, $criterion, $levelsstr, $criterionvalue);
ab156741 382 }
3c2b3cb3 383 return $this->rubric_template($mode, $options, $elementname, $criteriastr);
ab156741
MG
384 }
385
386 /**
fc5adc3b 387 * Help function to return CSS class names for element (first/last/even/odd) with leading space
ab156741 388 *
3c2b3cb3
MG
389 * @param int $idx index of this element in the row/column
390 * @param int $maxidx maximum index of the element in the row/column
ab156741
MG
391 * @return string
392 */
3c2b3cb3 393 protected function get_css_class_suffix($idx, $maxidx) {
ab156741 394 $class = '';
3c2b3cb3 395 if ($idx == 0) {
ab156741
MG
396 $class .= ' first';
397 }
3c2b3cb3 398 if ($idx == $maxidx) {
ab156741
MG
399 $class .= ' last';
400 }
3c2b3cb3 401 if ($idx%2) {
ab156741
MG
402 $class .= ' odd';
403 } else {
404 $class .= ' even';
405 }
406 return $class;
407 }
36937f02
MG
408
409 /**
410 * Displays for the student the list of instances or default content if no instances found
411 *
412 * @param array $instances array of objects of type gradingform_rubric_instance
413 * @param string $defaultcontent default string that would be displayed without advanced grading
0136124e 414 * @param boolean $cangrade whether current user has capability to grade in this context
36937f02
MG
415 * @return string
416 */
0136124e 417 public function display_instances($instances, $defaultcontent, $cangrade) {
3c2b3cb3 418 $return = '';
36937f02 419 if (sizeof($instances)) {
3c2b3cb3 420 $return .= html_writer::start_tag('div', array('class' => 'advancedgrade'));
36937f02
MG
421 $idx = 0;
422 foreach ($instances as $instance) {
3c2b3cb3 423 $return .= $this->display_instance($instance, $idx++, $cangrade);
36937f02 424 }
3c2b3cb3 425 $return .= html_writer::end_tag('div');
36937f02 426 }
3c2b3cb3 427 return $return. $defaultcontent;
36937f02
MG
428 }
429
430 /**
431 * Displays one grading instance
432 *
433 * @param gradingform_rubric_instance $instance
d22e9e32
MG
434 * @param int $idx unique number of instance on page
435 * @param bool $cangrade whether current user has capability to grade in this context
36937f02 436 */
0136124e 437 public function display_instance(gradingform_rubric_instance $instance, $idx, $cangrade) {
36937f02 438 $criteria = $instance->get_controller()->get_definition()->rubric_criteria;
39c6f4b6 439 $options = $instance->get_controller()->get_options();
36937f02 440 $values = $instance->get_rubric_filling();
0136124e
MG
441 if ($cangrade) {
442 $mode = gradingform_rubric_controller::DISPLAY_REVIEW;
577c8964 443 $showdescription = $options['showdescriptionteacher'];
0136124e
MG
444 } else {
445 $mode = gradingform_rubric_controller::DISPLAY_VIEW;
577c8964 446 $showdescription = $options['showdescriptionstudent'];
0136124e 447 }
577c8964
MG
448 $output = '';
449 if ($showdescription) {
450 $output .= $this->box($instance->get_controller()->get_formatted_description(), 'gradingform_rubric-description');
451 }
452 $output .= $this->display_rubric($criteria, $options, $mode, 'rubric'.$idx, $values);
453 return $output;
0136124e
MG
454 }
455
d22e9e32
MG
456 /**
457 * Displays confirmation that students require re-grading
458 *
459 * @param string $elementname
460 * @param int $changelevel
461 * @param string $value
462 * @return string
463 */
0136124e
MG
464 public function display_regrade_confirmation($elementname, $changelevel, $value) {
465 $html = html_writer::start_tag('div', array('class' => 'gradingform_rubric-regrade'));
466 if ($changelevel<=2) {
29bea634 467 $html .= html_writer::label(get_string('regrademessage1', 'gradingform_rubric'), 'menu' . $elementname . 'regrade');
0136124e
MG
468 $selectoptions = array(
469 0 => get_string('regradeoption0', 'gradingform_rubric'),
470 1 => get_string('regradeoption1', 'gradingform_rubric')
471 );
472 $html .= html_writer::select($selectoptions, $elementname.'[regrade]', $value, false);
473 } else {
474 $html .= get_string('regrademessage5', 'gradingform_rubric');
475 $html .= html_writer::empty_tag('input', array('name' => $elementname.'[regrade]', 'value' => 1, 'type' => 'hidden'));
476 }
477 $html .= html_writer::end_tag('div');
478 return $html;
36937f02 479 }
a19d1057
MG
480
481 /**
482 * Generates and returns HTML code to display information box about how rubric score is converted to the grade
483 *
484 * @param array $scores
485 * @return string
486 */
487 public function display_rubric_mapping_explained($scores) {
488 $html = '';
489 if (!$scores) {
490 return $html;
491 }
492 $html .= $this->box(
493 html_writer::tag('h4', get_string('rubricmapping', 'gradingform_rubric')).
494 html_writer::tag('div', get_string('rubricmappingexplained', 'gradingform_rubric', (object)$scores))
495 , 'generalbox rubricmappingexplained');
496 return $html;
497 }
c586d2bf 498}