MDL-29481: added css border around selected rubric level
[moodle.git] / grade / grading / form / rubric / rubriceditor.php
CommitLineData
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
25defined('MOODLE_INTERNAL') || die();
26
27require_once("HTML/QuickForm/input.php");
28
29// register file-related rules
30if (class_exists('HTML_QuickForm')) {
31 HTML_QuickForm::registerRule('rubriceditorcompleted', 'callback', '_ruleIsCompleted', 'MoodleQuickForm_rubriceditor');
32}
33
34class MoodleQuickForm_rubriceditor extends HTML_QuickForm_input {
35 public $_helpbutton = '';
36
37 function MoodleQuickForm_rubriceditor($elementName=null, $elementLabel=null, $attributes=null) {
38 parent::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
39 }
40
41 function getHelpButton() {
42 return $this->_helpbutton;
43 }
44
45 function getElementTemplateType() {
46 return 'default';
47 }
48
49 function toHtml() {
50 global $PAGE;
51 $html = $this->_getTabs();
ab156741 52 $renderer = $PAGE->get_renderer('gradingform_rubric');
39c6f4b6 53 $data = $this->prepare_non_js_data();
c586d2bf 54 if (!$this->_flagFrozen) {
ab156741
MG
55 $mode = gradingform_rubric_controller::DISPLAY_EDIT_FULL;
56 $module = array('name'=>'gradingform_rubriceditor', 'fullpath'=>'/grade/grading/form/rubric/js/rubriceditor.js',
57 'strings' => array(array('confirmdeletecriterion', 'gradingform_rubric'), array('confirmdeletelevel', 'gradingform_rubric'),
58 array('criterionempty', 'gradingform_rubric'), array('levelempty', 'gradingform_rubric')
59 ));
60 $PAGE->requires->js_init_call('M.gradingform_rubriceditor.init', array(
61 array('name' => $this->getName(),
39c6f4b6
MG
62 'criteriontemplate' => $renderer->criterion_template($mode, $data['options'], $this->getName()),
63 'leveltemplate' => $renderer->level_template($mode, $data['options'], $this->getName())
ab156741
MG
64 )),
65 true, $module);
c586d2bf 66 } else {
39c6f4b6 67 // Rubric is frozen, no javascript needed
c586d2bf 68 if ($this->_persistantFreeze) {
ab156741
MG
69 $mode = gradingform_rubric_controller::DISPLAY_EDIT_FROZEN;
70 } else {
71 $mode = gradingform_rubric_controller::DISPLAY_PREVIEW;
c586d2bf 72 }
c586d2bf 73 }
39c6f4b6 74 $html .= $renderer->display_rubric($data['criteria'], $data['options'], $mode, $this->getName());
c586d2bf
MG
75 return $html;
76 }
77
39c6f4b6
MG
78 /**
79 * Prepares the data passed in $_POST:
80 * - processes the pressed buttons 'addlevel', 'addcriterion', 'moveup', 'movedown', 'delete' (when JavaScript is disabled)
81 * - if options not passed (i.e. we create a new rubric) fills the options array with the default values
82 * - if options are passed completes the options array with unchecked checkboxes
83 *
84 * @param array $value
85 * @return array
86 */
87 function prepare_non_js_data($value = null) {
88 if (null === $value) {
89 $value = $this->getValue();
90 }
91 $return = array('criteria' => array(), 'options' => gradingform_rubric_controller::get_default_options());
92 if (!isset($value['criteria'])) {
93 $value['criteria'] = array();
94 }
95 if (!empty($value['options'])) {
96 foreach (array_keys($return['options']) as $option) {
97 // special treatment for checkboxes
98 if (!empty($value['options'][$option])) {
99 $return['options'][$option] = $value['options'][$option];
100 } else {
101 $return['options'][$option] = null;
102 }
103 }
c586d2bf
MG
104 }
105 $lastaction = null;
106 $lastid = null;
39c6f4b6 107 foreach ($value['criteria'] as $id => $criterion) {
c586d2bf 108 if ($id == 'addcriterion') {
39c6f4b6 109 $id = $this->get_next_id(array_keys($value['criteria']));
c586d2bf
MG
110 $criterion = array('description' => '');
111 }
112 $levels = array();
113 if (array_key_exists('levels', $criterion)) {
114 foreach ($criterion['levels'] as $levelid => $level) {
115 if ($levelid == 'addlevel') {
116 $levelid = $this->get_next_id(array_keys($criterion['levels']));
117 $level = array(
118 'definition' => '',
119 'score' => 0,
120 );
121 }
122 if (!array_key_exists('delete', $level)) {
123 $levels[$levelid] = $level;
124 }
125 }
126 }
127 $criterion['levels'] = $levels;
128 if (array_key_exists('moveup', $criterion) || $lastaction == 'movedown') {
129 unset($criterion['moveup']);
130 if ($lastid !== null) {
39c6f4b6
MG
131 $lastcriterion = $return['criteria'][$lastid];
132 unset($return['criteria'][$lastid]);
133 $return['criteria'][$id] = $criterion;
134 $return['criteria'][$lastid] = $lastcriterion;
c586d2bf 135 } else {
39c6f4b6 136 $return['criteria'][$id] = $criterion;
c586d2bf
MG
137 }
138 $lastaction = null;
139 $lastid = $id;
140 } else if (array_key_exists('delete', $criterion)) {
141 } else {
142 if (array_key_exists('movedown', $criterion)) {
143 unset($criterion['movedown']);
144 $lastaction = 'movedown';
145 }
39c6f4b6 146 $return['criteria'][$id] = $criterion;
c586d2bf
MG
147 $lastid = $id;
148 }
149 }
150 $csortorder = 1;
39c6f4b6
MG
151 foreach (array_keys($return['criteria']) as $id) {
152 $return['criteria'][$id]['sortorder'] = $csortorder++;
c586d2bf
MG
153 }
154 return $return;
155 }
156
157 function get_next_id($ids) {
158 $maxid = 0;
159 foreach ($ids as $id) {
160 if (preg_match('/^NEWID(\d+)$/', $id, $matches) && ((int)$matches[1]) > $maxid) {
161 $maxid = (int)$matches[1];
162 }
163 }
164 return 'NEWID'.($maxid+1);
165 }
166
167 function _ruleIsCompleted($elementValue) {
168 //echo "_ruleIsCompleted";
39c6f4b6
MG
169 if (isset($elementValue['criteria'])) {
170 foreach ($elementValue['criteria'] as $criterionid => $criterion) {
c586d2bf
MG
171 if ($criterionid == 'addcriterion') {
172 return false;
173 }
174 if (array_key_exists('moveup', $criterion) || array_key_exists('movedown', $criterion) || array_key_exists('delete', $criterion)) {
175 return false;
176 }
177 if (array_key_exists('levels', $criterion) && is_array($criterion['levels'])) {
178 foreach ($criterion['levels'] as $levelid => $level) {
179 if ($levelid == 'addlevel') {
180 return false;
181 }
182 if (array_key_exists('delete', $level)) {
183 return false;
184 }
185 }
186 }
187 }
188 }
189 //TODO check everything is filled
190 //echo "<pre>";print_r($elementValue);echo "</pre>";
191 return true;
192 }
193
194 function onQuickFormEvent($event, $arg, &$caller)
195 {
196 $name = $this->getName();
197 if ($name && $caller->elementExists($name)) {
198 $caller->addRule($name, '', 'rubriceditorcompleted');
199 }
200 return parent::onQuickFormEvent($event, $arg, $caller);
201 }
202
39c6f4b6
MG
203 /**
204 * Prepares the data for saving
205 * @see prepare_non_js_data
206 *
207 * @param array $submitValues
208 * @param boolean $assoc
209 * @return array
210 */
211 function exportValue(&$submitValues, $assoc = false) {
212 $value = $this->prepare_non_js_data($this->_findValue($submitValues));
213 return $this->_prepareValue($value, $assoc);
214 }
c586d2bf 215}