PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/grade/grading/form/rubric/renderer.php

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