|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00025 defined('MOODLE_INTERNAL') || die(); 00026 00030 class gradingform_rubric_renderer extends plugin_renderer_base { 00031 00054 public function criterion_template($mode, $options, $elementname = '{NAME}', $criterion = null, $levelsstr = '{LEVELS}', $value = null) { 00055 // TODO description format, remark format 00056 if ($criterion === null || !is_array($criterion) || !array_key_exists('id', $criterion)) { 00057 $criterion = array('id' => '{CRITERION-id}', 'description' => '{CRITERION-description}', 'sortorder' => '{CRITERION-sortorder}', 'class' => '{CRITERION-class}'); 00058 } else { 00059 foreach (array('sortorder', 'description', 'class') as $key) { 00060 // set missing array elements to empty strings to avoid warnings 00061 if (!array_key_exists($key, $criterion)) { 00062 $criterion[$key] = ''; 00063 } 00064 } 00065 } 00066 $criteriontemplate = html_writer::start_tag('tr', array('class' => 'criterion'. $criterion['class'], 'id' => '{NAME}-criteria-{CRITERION-id}')); 00067 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { 00068 $criteriontemplate .= html_writer::start_tag('td', array('class' => 'controls')); 00069 foreach (array('moveup', 'delete', 'movedown') as $key) { 00070 $value = get_string('criterion'.$key, 'gradingform_rubric'); 00071 $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}]['.$key.']', 00072 'id' => '{NAME}-criteria-{CRITERION-id}-'.$key, 'value' => $value, 'title' => $value, 'tabindex' => -1)); 00073 $criteriontemplate .= html_writer::tag('div', $button, array('class' => $key)); 00074 } 00075 $criteriontemplate .= html_writer::end_tag('td'); // .controls 00076 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder'])); 00077 $description = html_writer::tag('textarea', htmlspecialchars($criterion['description']), array('name' => '{NAME}[criteria][{CRITERION-id}][description]', 'cols' => '10', 'rows' => '5')); 00078 } else { 00079 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) { 00080 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][sortorder]', 'value' => $criterion['sortorder'])); 00081 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][description]', 'value' => $criterion['description'])); 00082 } 00083 $description = $criterion['description']; 00084 } 00085 $descriptionclass = 'description'; 00086 if (isset($criterion['error_description'])) { 00087 $descriptionclass .= ' error'; 00088 } 00089 $criteriontemplate .= html_writer::tag('td', $description, array('class' => $descriptionclass, 'id' => '{NAME}-criteria-{CRITERION-id}-description')); 00090 $levelsstrtable = html_writer::tag('table', html_writer::tag('tr', $levelsstr, array('id' => '{NAME}-criteria-{CRITERION-id}-levels'))); 00091 $levelsclass = 'levels'; 00092 if (isset($criterion['error_levels'])) { 00093 $levelsclass .= ' error'; 00094 } 00095 $criteriontemplate .= html_writer::tag('td', $levelsstrtable, array('class' => $levelsclass)); 00096 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { 00097 $value = get_string('criterionaddlevel', 'gradingform_rubric'); 00098 $button = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][addlevel]', 00099 'id' => '{NAME}-criteria-{CRITERION-id}-levels-addlevel', 'value' => $value, 'title' => $value)); 00100 $criteriontemplate .= html_writer::tag('td', $button, array('class' => 'addlevel')); 00101 } 00102 $displayremark = ($options['enableremarks'] && ($mode != gradingform_rubric_controller::DISPLAY_VIEW || $options['showremarksstudent'])); 00103 if ($displayremark) { 00104 $currentremark = ''; 00105 if (isset($value['remark'])) { 00106 $currentremark = $value['remark']; 00107 } 00108 if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) { 00109 $input = html_writer::tag('textarea', htmlspecialchars($currentremark), array('name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'cols' => '10', 'rows' => '5')); 00110 $criteriontemplate .= html_writer::tag('td', $input, array('class' => 'remark')); 00111 } else if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN) { 00112 $criteriontemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][remark]', 'value' => $currentremark)); 00113 }else if ($mode == gradingform_rubric_controller::DISPLAY_REVIEW || $mode == gradingform_rubric_controller::DISPLAY_VIEW) { 00114 $criteriontemplate .= html_writer::tag('td', $currentremark, array('class' => 'remark')); // TODO maybe some prefix here like 'Teacher remark:' 00115 } 00116 } 00117 $criteriontemplate .= html_writer::end_tag('tr'); // .criterion 00118 00119 $criteriontemplate = str_replace('{NAME}', $elementname, $criteriontemplate); 00120 $criteriontemplate = str_replace('{CRITERION-id}', $criterion['id'], $criteriontemplate); 00121 return $criteriontemplate; 00122 } 00123 00145 public function level_template($mode, $options, $elementname = '{NAME}', $criterionid = '{CRITERION-id}', $level = null) { 00146 // TODO definition format 00147 if (!isset($level['id'])) { 00148 $level = array('id' => '{LEVEL-id}', 'definition' => '{LEVEL-definition}', 'score' => '{LEVEL-score}', 'class' => '{LEVEL-class}', 'checked' => false); 00149 } else { 00150 foreach (array('score', 'definition', 'class', 'checked') as $key) { 00151 // set missing array elements to empty strings to avoid warnings 00152 if (!array_key_exists($key, $level)) { 00153 $level[$key] = ''; 00154 } 00155 } 00156 } 00157 00158 // Template for one level within one criterion 00159 $tdattributes = array('id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}', 'class' => 'level'. $level['class']); 00160 if (isset($level['tdwidth'])) { 00161 $tdattributes['width'] = round($level['tdwidth']).'%'; 00162 } 00163 $leveltemplate = html_writer::start_tag('td', $tdattributes); 00164 $leveltemplate .= html_writer::start_tag('div', array('class' => 'level-wrapper')); 00165 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { 00166 $definition = html_writer::tag('textarea', htmlspecialchars($level['definition']), array('name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'cols' => '10', 'rows' => '4')); 00167 $score = html_writer::empty_tag('input', array('type' => 'text', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][score]', 'size' => '3', 'value' => $level['score'])); 00168 } else { 00169 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) { 00170 $leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][definition]', 'value' => $level['definition'])); 00171 $leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levels][{LEVEL-id}][score]', 'value' => $level['score'])); 00172 } 00173 $definition = $level['definition']; 00174 $score = $level['score']; 00175 } 00176 if ($mode == gradingform_rubric_controller::DISPLAY_EVAL) { 00177 $input = html_writer::empty_tag('input', array('type' => 'radio', 'name' => '{NAME}[criteria][{CRITERION-id}][levelid]', 'value' => $level['id']) + 00178 ($level['checked'] ? array('checked' => 'checked') : array())); 00179 $leveltemplate .= html_writer::tag('div', $input, array('class' => 'radio')); 00180 } 00181 if ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN && $level['checked']) { 00182 $leveltemplate .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => '{NAME}[criteria][{CRITERION-id}][levelid]', 'value' => $level['id'])); 00183 } 00184 $score = html_writer::tag('span', $score, array('id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-score', 'class' => 'scorevalue')); 00185 $definitionclass = 'definition'; 00186 if (isset($level['error_definition'])) { 00187 $definitionclass .= ' error'; 00188 } 00189 $leveltemplate .= html_writer::tag('div', $definition, array('class' => $definitionclass, 'id' => '{NAME}-criteria-{CRITERION-id}-levels-{LEVEL-id}-definition')); 00190 $displayscore = true; 00191 if (!$options['showscoreteacher'] && in_array($mode, array(gradingform_rubric_controller::DISPLAY_EVAL, gradingform_rubric_controller::DISPLAY_EVAL_FROZEN, gradingform_rubric_controller::DISPLAY_REVIEW))) { 00192 $displayscore = false; 00193 } 00194 if (!$options['showscorestudent'] && in_array($mode, array(gradingform_rubric_controller::DISPLAY_VIEW, gradingform_rubric_controller::DISPLAY_PREVIEW_GRADED))) { 00195 $displayscore = false; 00196 } 00197 if ($displayscore) { 00198 $scoreclass = 'score'; 00199 if (isset($level['error_score'])) { 00200 $scoreclass .= ' error'; 00201 } 00202 $leveltemplate .= html_writer::tag('div', get_string('scorepostfix', 'gradingform_rubric', $score), array('class' => $scoreclass)); 00203 } 00204 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { 00205 $value = get_string('leveldelete', 'gradingform_rubric'); 00206 $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)); 00207 $leveltemplate .= html_writer::tag('div', $button, array('class' => 'delete')); 00208 } 00209 $leveltemplate .= html_writer::end_tag('div'); // .level-wrapper 00210 $leveltemplate .= html_writer::end_tag('td'); // .level 00211 00212 $leveltemplate = str_replace('{NAME}', $elementname, $leveltemplate); 00213 $leveltemplate = str_replace('{CRITERION-id}', $criterionid, $leveltemplate); 00214 $leveltemplate = str_replace('{LEVEL-id}', $level['id'], $leveltemplate); 00215 return $leveltemplate; 00216 } 00217 00236 protected function rubric_template($mode, $options, $elementname, $criteriastr) { 00237 $classsuffix = ''; // CSS suffix for class of the main div. Depends on the mode 00238 switch ($mode) { 00239 case gradingform_rubric_controller::DISPLAY_EDIT_FULL: 00240 $classsuffix = ' editor editable'; break; 00241 case gradingform_rubric_controller::DISPLAY_EDIT_FROZEN: 00242 $classsuffix = ' editor frozen'; break; 00243 case gradingform_rubric_controller::DISPLAY_PREVIEW: 00244 case gradingform_rubric_controller::DISPLAY_PREVIEW_GRADED: 00245 $classsuffix = ' editor preview'; break; 00246 case gradingform_rubric_controller::DISPLAY_EVAL: 00247 $classsuffix = ' evaluate editable'; break; 00248 case gradingform_rubric_controller::DISPLAY_EVAL_FROZEN: 00249 $classsuffix = ' evaluate frozen'; break; 00250 case gradingform_rubric_controller::DISPLAY_REVIEW: 00251 $classsuffix = ' review'; break; 00252 case gradingform_rubric_controller::DISPLAY_VIEW: 00253 $classsuffix = ' view'; break; 00254 } 00255 00256 $rubrictemplate = html_writer::start_tag('div', array('id' => 'rubric-{NAME}', 'class' => 'clearfix gradingform_rubric'.$classsuffix)); 00257 $rubrictemplate .= html_writer::tag('table', $criteriastr, array('class' => 'criteria', 'id' => '{NAME}-criteria')); 00258 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { 00259 $value = get_string('addcriterion', 'gradingform_rubric'); 00260 $input = html_writer::empty_tag('input', array('type' => 'submit', 'name' => '{NAME}[criteria][addcriterion]', 'id' => '{NAME}-criteria-addcriterion', 'value' => $value, 'title' => $value)); 00261 $rubrictemplate .= html_writer::tag('div', $input, array('class' => 'addcriterion')); 00262 } 00263 $rubrictemplate .= $this->rubric_edit_options($mode, $options); 00264 $rubrictemplate .= html_writer::end_tag('div'); 00265 00266 return str_replace('{NAME}', $elementname, $rubrictemplate); 00267 } 00268 00277 protected function rubric_edit_options($mode, $options) { 00278 if ($mode != gradingform_rubric_controller::DISPLAY_EDIT_FULL 00279 && $mode != gradingform_rubric_controller::DISPLAY_EDIT_FROZEN 00280 && $mode != gradingform_rubric_controller::DISPLAY_PREVIEW) { 00281 // Options are displayed only for people who can manage 00282 return; 00283 } 00284 $html = html_writer::start_tag('div', array('class' => 'options')); 00285 $html .= html_writer::tag('div', get_string('rubricoptions', 'gradingform_rubric'), array('class' => 'optionsheading')); 00286 $attrs = array('type' => 'hidden', 'name' => '{NAME}[options][optionsset]', 'value' => 1); 00287 foreach ($options as $option => $value) { 00288 $html .= html_writer::start_tag('div', array('class' => 'option '.$option)); 00289 $attrs = array('name' => '{NAME}[options]['.$option.']', 'id' => '{NAME}-options-'.$option); 00290 switch ($option) { 00291 case 'sortlevelsasc': 00292 // Display option as dropdown 00293 $html .= html_writer::tag('span', get_string($option, 'gradingform_rubric'), array('class' => 'label')); 00294 $value = (int)(!!$value); // make sure $value is either 0 or 1 00295 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FULL) { 00296 $selectoptions = array(0 => get_string($option.'0', 'gradingform_rubric'), 1 => get_string($option.'1', 'gradingform_rubric')); 00297 $valuestr = html_writer::select($selectoptions, $attrs['name'], $value, false, array('id' => $attrs['id'])); 00298 $html .= html_writer::tag('span', $valuestr, array('class' => 'value')); 00299 // TODO add here button 'Sort levels' 00300 } else { 00301 $html .= html_writer::tag('span', get_string($option.$value, 'gradingform_rubric'), array('class' => 'value')); 00302 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN) { 00303 $html .= html_writer::empty_tag('input', $attrs + array('type' => 'hidden', 'value' => $value)); 00304 } 00305 } 00306 break; 00307 default: 00308 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN && $value) { 00309 $html .= html_writer::empty_tag('input', $attrs + array('type' => 'hidden', 'value' => $value)); 00310 } 00311 // Display option as checkbox 00312 $attrs['type'] = 'checkbox'; 00313 $attrs['value'] = 1; 00314 if ($value) { 00315 $attrs['checked'] = 'checked'; 00316 } 00317 if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_PREVIEW) { 00318 $attrs['disabled'] = 'disabled'; 00319 unset($attrs['name']); 00320 } 00321 $html .= html_writer::empty_tag('input', $attrs); 00322 $html .= html_writer::tag('label', get_string($option, 'gradingform_rubric'), array('for' => $attrs['id'])); 00323 break; 00324 } 00325 $html .= html_writer::end_tag('div'); // .option 00326 } 00327 $html .= html_writer::end_tag('div'); // .options 00328 return $html; 00329 } 00330 00346 public function display_rubric($criteria, $options, $mode, $elementname = null, $values = null) { 00347 $criteriastr = ''; 00348 $cnt = 0; 00349 foreach ($criteria as $id => $criterion) { 00350 $criterion['class'] = $this->get_css_class_suffix($cnt++, sizeof($criteria) -1); 00351 $criterion['id'] = $id; 00352 $levelsstr = ''; 00353 $levelcnt = 0; 00354 if (isset($values['criteria'][$id])) { 00355 $criterionvalue = $values['criteria'][$id]; 00356 } else { 00357 $criterionvalue = null; 00358 } 00359 foreach ($criterion['levels'] as $levelid => $level) { 00360 $level['id'] = $levelid; 00361 $level['class'] = $this->get_css_class_suffix($levelcnt++, sizeof($criterion['levels']) -1); 00362 $level['checked'] = (isset($criterionvalue['levelid']) && ((int)$criterionvalue['levelid'] === $levelid)); 00363 if ($level['checked'] && ($mode == gradingform_rubric_controller::DISPLAY_EVAL_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_REVIEW || $mode == gradingform_rubric_controller::DISPLAY_VIEW)) { 00364 $level['class'] .= ' checked'; 00365 //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 00366 } 00367 if (isset($criterionvalue['savedlevelid']) && ((int)$criterionvalue['savedlevelid'] === $levelid)) { 00368 $level['class'] .= ' currentchecked'; 00369 } 00370 $level['tdwidth'] = 100/count($criterion['levels']); 00371 $levelsstr .= $this->level_template($mode, $options, $elementname, $id, $level); 00372 } 00373 $criteriastr .= $this->criterion_template($mode, $options, $elementname, $criterion, $levelsstr, $criterionvalue); 00374 } 00375 return $this->rubric_template($mode, $options, $elementname, $criteriastr); 00376 } 00377 00385 protected function get_css_class_suffix($idx, $maxidx) { 00386 $class = ''; 00387 if ($idx == 0) { 00388 $class .= ' first'; 00389 } 00390 if ($idx == $maxidx) { 00391 $class .= ' last'; 00392 } 00393 if ($idx%2) { 00394 $class .= ' odd'; 00395 } else { 00396 $class .= ' even'; 00397 } 00398 return $class; 00399 } 00400 00409 public function display_instances($instances, $defaultcontent, $cangrade) { 00410 $return = ''; 00411 if (sizeof($instances)) { 00412 $return .= html_writer::start_tag('div', array('class' => 'advancedgrade')); 00413 $idx = 0; 00414 foreach ($instances as $instance) { 00415 $return .= $this->display_instance($instance, $idx++, $cangrade); 00416 } 00417 $return .= html_writer::end_tag('div'); 00418 } 00419 return $return. $defaultcontent; 00420 } 00421 00429 public function display_instance(gradingform_rubric_instance $instance, $idx, $cangrade) { 00430 $criteria = $instance->get_controller()->get_definition()->rubric_criteria; 00431 $options = $instance->get_controller()->get_options(); 00432 $values = $instance->get_rubric_filling(); 00433 if ($cangrade) { 00434 $mode = gradingform_rubric_controller::DISPLAY_REVIEW; 00435 $showdescription = $options['showdescriptionteacher']; 00436 } else { 00437 $mode = gradingform_rubric_controller::DISPLAY_VIEW; 00438 $showdescription = $options['showdescriptionstudent']; 00439 } 00440 $output = ''; 00441 if ($showdescription) { 00442 $output .= $this->box($instance->get_controller()->get_formatted_description(), 'gradingform_rubric-description'); 00443 } 00444 $output .= $this->display_rubric($criteria, $options, $mode, 'rubric'.$idx, $values); 00445 return $output; 00446 } 00447 00448 public function display_regrade_confirmation($elementname, $changelevel, $value) { 00449 $html = html_writer::start_tag('div', array('class' => 'gradingform_rubric-regrade')); 00450 if ($changelevel<=2) { 00451 $html .= get_string('regrademessage1', 'gradingform_rubric'); 00452 $selectoptions = array( 00453 0 => get_string('regradeoption0', 'gradingform_rubric'), 00454 1 => get_string('regradeoption1', 'gradingform_rubric') 00455 ); 00456 $html .= html_writer::select($selectoptions, $elementname.'[regrade]', $value, false); 00457 } else { 00458 $html .= get_string('regrademessage5', 'gradingform_rubric'); 00459 $html .= html_writer::empty_tag('input', array('name' => $elementname.'[regrade]', 'value' => 1, 'type' => 'hidden')); 00460 } 00461 $html .= html_writer::end_tag('div'); 00462 return $html; 00463 } 00464 00471 public function display_rubric_mapping_explained($scores) { 00472 $html = ''; 00473 if (!$scores) { 00474 return $html; 00475 } 00476 $html .= $this->box( 00477 html_writer::tag('h4', get_string('rubricmapping', 'gradingform_rubric')). 00478 html_writer::tag('div', get_string('rubricmappingexplained', 'gradingform_rubric', (object)$scores)) 00479 , 'generalbox rubricmappingexplained'); 00480 return $html; 00481 } 00482 }