Commit | Line | Data |
---|---|---|
c586d2bf MG |
1 | <?php |
2 | ||
3 | // This file is part of Moodle - http://moodle.org/ | |
4 | // | |
5 | // Moodle is free software: you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
18 | /** | |
19 | * @package gradingform | |
20 | * @subpackage rubric | |
21 | * @copyright 2011 Marina Glancy | |
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
23 | */ | |
24 | ||
25 | ||
26 | defined('MOODLE_INTERNAL') || die(); | |
27 | ||
28 | /** | |
29 | * Grading method plugin renderer | |
30 | */ | |
ab156741 | 31 | class gradingform_rubric_renderer { |
c586d2bf | 32 | |
ab156741 MG |
33 | /** |
34 | * | |
35 | * @param int $mode @see gradingform_rubric_controller | |
36 | * @return string | |
37 | */ | |
38 | public function criterion_template($mode, $elementname = '{NAME}', $criterion = null, $levels_str = '{LEVELS}') { | |
39 | // TODO description format | |
40 | if ($criterion === null || !is_array($criterion) || !array_key_exists('id', $criterion)) { | |
41 | $criterion = array('id' => '{CRITERION-id}', 'description' => '{CRITERION-description}', 'sortorder' => '{CRITERION-sortorder}', 'class' => '{CRITERION-class}'); | |
42 | } else { | |
43 | foreach (array('sortorder', 'description', 'class') as $key) { | |
44 | // set missing array elements to empty strings to avoid warnings | |
45 | if (!array_key_exists($key, $criterion)) { | |
46 | $criterion[$key] = ''; | |
47 | } | |
48 | } | |
49 | } | |
50 | $criterion_template = html_writer::start_tag('div', array('class' => 'clearfix criterion'. $criterion['class'], 'id' => '{NAME}-{CRITERION-id}')); | |
51 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { | |
52 | $criterion_template .= html_writer::start_tag('div', array('class' => 'controls')); | |
53 | foreach (array('moveup', 'delete', 'movedown') as $key) { | |
54 | $value = get_string('criterion'.$key, 'gradingform_rubric'); | |
55 | $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}]['.$key.']', | |
56 | 'id' => '{NAME}-{CRITERION-id}-'.$key, 'value' => $value, 'title' => $value)); | |
57 | $criterion_template .= html_writer::tag('div', $button, array('class' => $key)); | |
58 | } | |
59 | $criterion_template .= html_writer::end_tag('div'); // .controls | |
60 | $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder'])); | |
61 | $description = html_writer::tag('textarea', htmlspecialchars($criterion['description']), array('name' => '{NAME}[{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5')); | |
62 | } else { | |
63 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) { | |
64 | $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder'])); | |
65 | $criterion_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][description]', 'value' => $criterion['description'])); | |
66 | } | |
67 | $description = $criterion['description']; | |
68 | } | |
69 | $criterion_template .= html_writer::tag('div', $description, array('class' => 'description', 'id' => '{NAME}-{CRITERION-id}-description')); | |
70 | $criterion_template .= html_writer::tag('div', $levels_str, array('class' => 'clearfix levels', 'id' => '{NAME}-{CRITERION-id}-levels')); | |
71 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { | |
72 | $value = get_string('criterionaddlevel', 'gradingform_rubric'); | |
73 | $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}][levels][addlevel]', | |
74 | 'id' => '{NAME}-{CRITERION-id}-levels-addlevel', 'value' => $value, 'title' => $value)); //TODO '{NAME}-{CRITERION-id}-levels-addlevel | |
75 | $criterion_template .= html_writer::tag('div', $button, array('class' => 'addlevel')); | |
76 | } | |
77 | $criterion_template .= html_writer::end_tag('div'); // .criterion | |
78 | ||
79 | $criterion_template = str_replace('{NAME}', $elementname, $criterion_template); | |
80 | $criterion_template = str_replace('{CRITERION-id}', $criterion['id'], $criterion_template); | |
81 | return $criterion_template; | |
82 | } | |
83 | ||
84 | public function level_template($mode, $elementname = '{NAME}', $criterionid = '{CRITERION-id}', $level = null) { | |
85 | // TODO definition format | |
86 | if ($level === null || !is_array($level) || !array_key_exists('id', $level)) { | |
87 | $level = array('id' => '{LEVEL-id}', 'definition' => '{LEVEL-definition}', 'score' => '{LEVEL-score}', 'class' => '{LEVEL-class}', 'checked' => false); | |
88 | } else { | |
89 | foreach (array('score', 'definition', 'class', 'checked') as $key) { | |
90 | // set missing array elements to empty strings to avoid warnings | |
91 | if (!array_key_exists($key, $level)) { | |
92 | $level[$key] = ''; | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
97 | // Template for one level within one criterion | |
98 | $level_template = html_writer::start_tag('div', array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}', 'class' => 'clearfix level'. $level['class'])); | |
99 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { | |
100 | $definition = html_writer::tag('textarea', htmlspecialchars($level['definition']), array('name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4')); | |
101 | $score = html_writer::empty_tag('input', array('type' => 'text', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][score]', 'size' => '4', 'value' => $level['score'])); | |
102 | } else { | |
103 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) { | |
104 | $level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][definition]', 'value' => $level['definition'])); | |
105 | $level_template .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][score]', 'value' => $level['score'])); | |
106 | } | |
107 | $definition = $level['definition']; | |
108 | $score = $level['score']; | |
109 | } | |
110 | if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) { | |
111 | $input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => '{NAME}[{CRITERION-id}]', 'value' => $level['id']) + | |
112 | ($level['checked'] ? array('checked' => 'checked') : array())); | |
113 | $level_template .= html_writer::tag('div', $input, array('class' => 'radio')); | |
114 | } | |
115 | if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN && $level['checked']) { | |
116 | $html .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[{CRITERION-id}]', 'value' => $level['id'])); | |
117 | } | |
118 | $score = html_writer::tag('span', $score, array('id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-score')); | |
119 | $level_template .= html_writer::tag('div', $definition, array('class' => 'definition', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-definition')); | |
120 | $level_template .= html_writer::tag('div', $score. get_string('scorepostfix', 'gradingform_rubric'), array('class' => 'score')); | |
121 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { | |
122 | $value = get_string('leveldelete', 'gradingform_rubric'); | |
123 | $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[{CRITERION-id}][levels][{LEVEL-id}][delete]', 'id' => '{NAME}-{CRITERION-id}-levels-{LEVEL-id}-delete', 'value' => $value, 'title' => $value)); | |
124 | $level_template .= html_writer::tag('div', $button, array('class' => 'delete')); | |
125 | } | |
126 | $level_template .= html_writer::end_tag('div'); // .level | |
127 | ||
128 | $level_template = str_replace('{NAME}', $elementname, $level_template); | |
129 | $level_template = str_replace('{CRITERION-id}', $criterionid, $level_template); | |
130 | $level_template = str_replace('{LEVEL-id}', $level['id'], $level_template); | |
131 | return $level_template; | |
132 | } | |
133 | ||
134 | protected function rubric_template($mode, $elementname = '{NAME}', $criteria_str = '{CRITERIA}') { | |
135 | $classsuffix = ''; // CSS suffix for class of the main div. Depends on the mode | |
136 | switch ($mode) { | |
137 | case gradingform_rubric_controller::DISPLAY_EDIT_FULL: | |
138 | $classsuffix = ' editor editable'; break; | |
139 | case gradingform_rubric_controller::DISPLAY_EDIT_FROZEN: | |
140 | $classsuffix = ' editor frozen'; break; | |
141 | case gradingform_rubric_controller::DISPLAY_PREVIEW: | |
142 | $classsuffix = ' editor preview'; break; | |
143 | case gradingform_rubric_controller::DISPLAY_EVAL: | |
144 | $classsuffix = ' evaluate editable'; break; | |
145 | case gradingform_rubric_controller::DISPLAY_EVAL_FROZEN: | |
146 | $classsuffix = ' evaluate frozen'; break; | |
147 | case gradingform_rubric_controller::DISPLAY_REVIEW: | |
148 | $classsuffix = ' review'; break; | |
149 | } | |
150 | ||
151 | $rubric_template = html_writer::start_tag('div', array('id' => 'rubric-{NAME}', 'class' => 'clearfix form_rubric'.$classsuffix)); | |
152 | $rubric_template .= html_writer::tag('div', $criteria_str, array('class' => 'criteria', 'id' => '{NAME}-criteria')); | |
153 | if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { | |
154 | $value = get_string('addcriterion', 'gradingform_rubric'); | |
155 | $input = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[addcriterion]', 'id' => '{NAME}-addcriterion', 'value' => $value, 'title' => $value)); | |
156 | $rubric_template .= html_writer::tag('div', $input, array('class' => 'addcriterion')); | |
157 | } | |
158 | $rubric_template .= html_writer::end_tag('div'); | |
159 | ||
160 | return str_replace('{NAME}', $elementname, $rubric_template); | |
161 | } | |
162 | ||
163 | /** | |
164 | * Returns html code for displaying the rubric in the specified mode | |
165 | * | |
166 | * @param array $criteria | |
167 | * @param int $mode | |
168 | * @param string $elementname | |
169 | * @param array $values | |
170 | * @return string | |
171 | */ | |
172 | public function display_rubric($criteria, $mode, $elementname = null, $values = null) { | |
173 | $criteria_str = ''; | |
174 | $cnt = 0; | |
175 | foreach ($criteria as $id => $criterion) { | |
176 | $criterion['class'] = $this->get_css_class_suffix($cnt++, sizeof($criteria) -1); | |
177 | $levels_str = ''; | |
178 | $levelcnt = 0; | |
179 | foreach ($criterion['levels'] as $levelid => $level) { | |
180 | $level['score'] = (float)$level['score']; // otherwise the display will look like 1.00000 | |
181 | $level['class'] = $this->get_css_class_suffix($levelcnt++, sizeof($criterion['levels']) -1); | |
182 | $level['checked'] = (is_array($values) && (array_key_exists($id, $values) && ((int)$values[$id] === $levelid))); | |
183 | if ($level['checked'] && ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_REVIEW)) { | |
184 | $level['class'] .= ' checked'; | |
185 | //in mode DISPLAY_EVAL the class 'checked' will be added by JS if it is enabled. If it is not enabled, the 'checked' class will only confuse | |
186 | } | |
187 | $levels_str .= $this->level_template($mode, $elementname, $id, $level); | |
188 | } | |
189 | $criteria_str .= $this->criterion_template($mode, $elementname, $criterion, $levels_str); | |
190 | } | |
191 | return $this->rubric_template($mode, $elementname, $criteria_str); | |
192 | } | |
193 | ||
194 | /** | |
195 | * Help function to return CSS class names for element (first/last/even/odd) | |
196 | * | |
197 | * @param <type> $cnt | |
198 | * @param <type> $maxcnt | |
199 | * @return string | |
200 | */ | |
201 | private function get_css_class_suffix($cnt, $maxcnt) { | |
202 | $class = ''; | |
203 | if ($cnt == 0) { | |
204 | $class .= ' first'; | |
205 | } | |
206 | if ($cnt == $maxcnt) { | |
207 | $class .= ' last'; | |
208 | } | |
209 | if ($cnt%2) { | |
210 | $class .= ' odd'; | |
211 | } else { | |
212 | $class .= ' even'; | |
213 | } | |
214 | return $class; | |
215 | } | |
c586d2bf | 216 | } |