MDL-22388 Added some checks to kill these scripts dead with an unequivocal notice...
[moodle.git] / grade / edit / tree / category_form.php
1 <?php
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/>.
18 if (!defined('MOODLE_INTERNAL')) {
19     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
20 }
22 require_once $CFG->libdir.'/formslib.php';
24 class edit_category_form extends moodleform {
25     private $aggregation_options = array();
27     function definition() {
28         global $CFG, $COURSE, $DB;
29         $mform =& $this->_form;
31         $category = $this->_customdata['current'];
33         $this->aggregation_options = array(GRADE_AGGREGATE_MEAN            =>get_string('aggregatemean', 'grades'),
34                                            GRADE_AGGREGATE_WEIGHTED_MEAN   =>get_string('aggregateweightedmean', 'grades'),
35                                            GRADE_AGGREGATE_WEIGHTED_MEAN2  =>get_string('aggregateweightedmean2', 'grades'),
36                                            GRADE_AGGREGATE_EXTRACREDIT_MEAN=>get_string('aggregateextracreditmean', 'grades'),
37                                            GRADE_AGGREGATE_MEDIAN          =>get_string('aggregatemedian', 'grades'),
38                                            GRADE_AGGREGATE_MIN             =>get_string('aggregatemin', 'grades'),
39                                            GRADE_AGGREGATE_MAX             =>get_string('aggregatemax', 'grades'),
40                                            GRADE_AGGREGATE_MODE            =>get_string('aggregatemode', 'grades'),
41                                            GRADE_AGGREGATE_SUM             =>get_string('aggregatesum', 'grades'));
43         // visible elements
44         $mform->addElement('header', 'headercategory', get_string('gradecategory', 'grades'));
45         $mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
46         $mform->addRule('fullname', null, 'required', null, 'client');
48         $mform->addElement('select', 'aggregation', get_string('aggregation', 'grades'), $this->aggregation_options);
49         $mform->setHelpButton('aggregation', array('aggregation', get_string('aggregation', 'grades'), 'grade'));
51         if ((int)$CFG->grade_aggregation_flag & 2) {
52             $mform->setAdvanced('aggregation');
53         }
55         $mform->addElement('checkbox', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades'));
56         $mform->setHelpButton('aggregateonlygraded', array('aggregateonlygraded', get_string('aggregateonlygraded', 'grades'),'grade'), true);
57         $mform->disabledIf('aggregateonlygraded', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
59         if ((int)$CFG->grade_aggregateonlygraded_flag & 2) {
60             $mform->setAdvanced('aggregateonlygraded');
61         }
63         if (empty($CFG->enableoutcomes)) {
64             $mform->addElement('hidden', 'aggregateoutcomes');
65             $mform->setType('aggregateoutcomes', PARAM_INT);
66         } else {
67             $mform->addElement('checkbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
68             $mform->setHelpButton('aggregateoutcomes', array('aggregateoutcomes', get_string('aggregateoutcomes', 'grades'), 'grade'), true);
69             if ((int)$CFG->grade_aggregateoutcomes_flag & 2) {
70                 $mform->setAdvanced('aggregateoutcomes');
71             }
72         }
74         $mform->addElement('advcheckbox', 'aggregatesubcats', get_string('aggregatesubcats', 'grades'));
75         $mform->setHelpButton('aggregatesubcats', array('aggregatesubcats', get_string('aggregatesubcats', 'grades'), 'grade'), true);
77         if ((int)$CFG->grade_aggregatesubcats_flag & 2) {
78             $mform->setAdvanced('aggregatesubcats');
79         }
81         $options = array(0 => get_string('none'));
83         for ($i=1; $i<=20; $i++) {
84             $options[$i] = $i;
85         }
87         $mform->addElement('select', 'keephigh', get_string('keephigh', 'grades'), $options);
88         $mform->setHelpButton('keephigh', array('keephigh', get_string('keephigh', 'grades'), 'grade'), true);
89         if ((int)$CFG->grade_keephigh_flag & 2) {
90             $mform->setAdvanced('keephigh');
91         }
93         $mform->addElement('select', 'droplow', get_string('droplow', 'grades'), $options);
94         $mform->setHelpButton('droplow', array('droplow', get_string('droplow', 'grades'), 'grade'), true);
95         $mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
96         if ((int)$CFG->grade_droplow_flag & 2) {
97             $mform->setAdvanced('droplow');
98         }
100         $mform->disabledIf('keephigh', 'droplow', 'noteq', 0);
101         $mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
103         // Grade item settings
104         $mform->addElement('header', 'general', get_string('gradeitem', 'grades'));
106         $mform->addElement('text', 'grade_item_itemname', get_string('itemname', 'grades'));
107         $mform->addElement('text', 'grade_item_iteminfo', get_string('iteminfo', 'grades'));
108         $mform->setHelpButton('grade_item_iteminfo', array('iteminfo', get_string('iteminfo', 'grades'), 'grade'), true);
110         $mform->addElement('text', 'grade_item_idnumber', get_string('idnumbermod'));
111         $mform->setHelpButton('grade_item_idnumber', array('idnumber', get_string('idnumber', 'grades'), 'grade'), true);
113         $options = array(GRADE_TYPE_NONE=>get_string('typenone', 'grades'),
114                          GRADE_TYPE_VALUE=>get_string('typevalue', 'grades'),
115                          GRADE_TYPE_SCALE=>get_string('typescale', 'grades'),
116                          GRADE_TYPE_TEXT=>get_string('typetext', 'grades'));
118         $mform->addElement('select', 'grade_item_gradetype', get_string('gradetype', 'grades'), $options);
119         $mform->setHelpButton('grade_item_gradetype', array('gradetype', get_string('gradetype', 'grades'), 'grade'), true);
120         $mform->setDefault('grade_item_gradetype', GRADE_TYPE_VALUE);
121         $mform->disabledIf('grade_item_gradetype', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
123         //$mform->addElement('text', 'calculation', get_string('calculation', 'grades'));
124         //$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT);
125         //$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE);
127         $options = array(0=>get_string('usenoscale', 'grades'));
128         if ($scales = grade_scale::fetch_all_local($COURSE->id)) {
129             foreach ($scales as $scale) {
130                 $options[$scale->id] = $scale->get_name();
131             }
132         }
133         if ($scales = grade_scale::fetch_all_global()) {
134             foreach ($scales as $scale) {
135                 $options[$scale->id] = $scale->get_name();
136             }
137         }
138         // ugly BC hack - it was possbile to use custom scale from other courses :-(
139         if (!empty($category->grade_item_scaleid) and !isset($options[$category->grade_item_scaleid])) {
140             if ($scale = grade_scale::fetch(array('id'=>$category->grade_item_scaleid))) {
141                 $options[$scale->id] = $scale->get_name().' '.get_string('incorrectcustomscale', 'grades');
142             }
143         }
144         $mform->addElement('select', 'grade_item_scaleid', get_string('scale'), $options);
145         $mform->setHelpButton('grade_item_scaleid', array('scaleid', get_string('scaleid', 'grades'), 'grade'), true);
146         $mform->disabledIf('grade_item_scaleid', 'grade_item_gradetype', 'noteq', GRADE_TYPE_SCALE);
147         $mform->disabledIf('grade_item_scaleid', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
149         $mform->addElement('text', 'grade_item_grademax', get_string('grademax', 'grades'));
150         $mform->setHelpButton('grade_item_grademax', array('grademax', get_string('grademax', 'grades'), 'grade'), true);
151         $mform->disabledIf('grade_item_grademax', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
152         $mform->disabledIf('grade_item_grademax', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
154         $mform->addElement('text', 'grade_item_grademin', get_string('grademin', 'grades'));
155         $mform->setHelpButton('grade_item_grademin', array('grademin', get_string('grademin', 'grades'), 'grade'), true);
156         $mform->disabledIf('grade_item_grademin', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
157         $mform->disabledIf('grade_item_grademin', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
159         $mform->addElement('text', 'grade_item_gradepass', get_string('gradepass', 'grades'));
160         $mform->setHelpButton('grade_item_gradepass', array('gradepass', get_string('gradepass', 'grades'), 'grade'), true);
161         $mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
162         $mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_TEXT);
164         /// grade display prefs
165         $default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype);
166         $options = array(GRADE_DISPLAY_TYPE_DEFAULT            => get_string('default', 'grades'),
167                          GRADE_DISPLAY_TYPE_REAL               => get_string('real', 'grades'),
168                          GRADE_DISPLAY_TYPE_PERCENTAGE         => get_string('percentage', 'grades'),
169                          GRADE_DISPLAY_TYPE_LETTER             => get_string('letter', 'grades'),
170                          GRADE_DISPLAY_TYPE_REAL_PERCENTAGE    => get_string('realpercentage', 'grades'),
171                          GRADE_DISPLAY_TYPE_REAL_LETTER        => get_string('realletter', 'grades'),
172                          GRADE_DISPLAY_TYPE_LETTER_REAL        => get_string('letterreal', 'grades'),
173                          GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE  => get_string('letterpercentage', 'grades'),
174                          GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER  => get_string('percentageletter', 'grades'),
175                          GRADE_DISPLAY_TYPE_PERCENTAGE_REAL    => get_string('percentagereal', 'grades')
176                          );
178         asort($options);
180         foreach ($options as $key=>$option) {
181             if ($key == $default_gradedisplaytype) {
182                 $options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
183                 break;
184             }
185         }
186         $mform->addElement('select', 'grade_item_display', get_string('gradedisplaytype', 'grades'), $options);
187         $mform->setHelpButton('grade_item_display', array('gradedisplaytype', get_string('gradedisplaytype', 'grades'), 'grade'), true);
189         $default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints);
190         $options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
191         $mform->addElement('select', 'grade_item_decimals', get_string('decimalpoints', 'grades'), $options);
192         $mform->setHelpButton('grade_item_decimals', array('decimalpoints', get_string('decimalpoints', 'grades'), 'grade'), true);
193         $mform->setDefault('grade_item_decimals', -1);
194         $mform->disabledIf('grade_item_decimals', 'grade_item_display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
196         if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
197             $mform->disabledIf('grade_item_decimals', 'grade_item_display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
198         }
200         /// hiding
201         // advcheckbox is not compatible with disabledIf!
202         $mform->addElement('checkbox', 'grade_item_hidden', get_string('hidden', 'grades'));
203         $mform->setHelpButton('grade_item_hidden', array('hidden', get_string('hidden', 'grades'), 'grade'));
204         $mform->addElement('date_time_selector', 'grade_item_hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
205         $mform->setHelpButton('grade_item_hiddenuntil', array('hiddenuntil', get_string('hiddenuntil', 'grades'), 'grade'));
206         $mform->disabledIf('grade_item_hidden', 'grade_item_hiddenuntil[off]', 'notchecked');
208         /// locking
209         $mform->addElement('checkbox', 'grade_item_locked', get_string('locked', 'grades'));
210         $mform->setHelpButton('grade_item_locked', array('locked', get_string('locked', 'grades'), 'grade'));
212         $mform->addElement('date_time_selector', 'grade_item_locktime', get_string('locktime', 'grades'), array('optional'=>true));
213         $mform->setHelpButton('grade_item_locktime', array('lockedafter', get_string('locktime', 'grades'), 'grade'));
214         $mform->disabledIf('grade_item_locktime', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
216 /// parent category related settings
217         $mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
219         $options = array();
220         $default = '';
221         $categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
223         foreach ($categories as $cat) {
224             $cat->apply_forced_settings();
225             $options[$cat->id] = $cat->get_name();
226             if ($cat->is_course_category()) {
227                 $default = $cat->id;
228             }
229         }
231         if (count($categories) > 1) {
232             $mform->addElement('select', 'parentcategory', get_string('parentcategory', 'grades'), $options);
233             $mform->addElement('static', 'currentparentaggregation', get_string('currentparentaggregation', 'grades'));
234         }
236         // hidden params
237         $mform->addElement('hidden', 'id', 0);
238         $mform->setType('id', PARAM_INT);
240         $mform->addElement('hidden', 'courseid', 0);
241         $mform->setType('courseid', PARAM_INT);
243 /// add return tracking info
244         $gpr = $this->_customdata['gpr'];
245         $gpr->add_mform_elements($mform);
247 /// mark advanced according to site settings
248         if (isset($CFG->grade_item_advanced)) {
249             $advanced = explode(',', $CFG->grade_item_advanced);
250             foreach ($advanced as $el) {
251                 $el = 'grade_item_'.$el;
252                 if ($mform->elementExists($el)) {
253                     $mform->setAdvanced($el);
254                 }
255             }
256         }
258 //-------------------------------------------------------------------------------
259         // buttons
260         $this->add_action_buttons();
261 //-------------------------------------------------------------------------------
262         $this->set_data($category);
263     }
266 /// tweak the form - depending on existing data
267     function definition_after_data() {
268         global $CFG, $COURSE;
270         $mform =& $this->_form;
272         $somecat = new grade_category();
274         foreach ($somecat->forceable as $property) {
275             if ((int)$CFG->{"grade_{$property}_flag"} & 1) {
276                 if ($mform->elementExists($property)) {
277                     if (empty($CFG->grade_hideforcedsettings)) {
278                         $mform->hardFreeze($property);
279                     } else {
280                         if ($mform->elementExists($property)) {
281                             $mform->removeElement($property);
282                         }
283                     }
284                 }
285             }
286         }
288         if ($CFG->grade_droplow > 0) {
289             if ($mform->elementExists('keephigh')) {
290                 $mform->removeElement('keephigh');
291             }
292         } else if ($CFG->grade_keephigh > 0) {
293             if ($mform->elementExists('droplow')) {
294                 $mform->removeElement('droplow');
295             }
296         }
298         if ($id = $mform->getElementValue('id')) {
299             $grade_category = grade_category::fetch(array('id'=>$id));
300             $grade_item = $grade_category->load_grade_item();
302             // remove agg coef if not used
303             if ($grade_category->is_course_category()) {
304                 if ($mform->elementExists('parentcategory')) {
305                     $mform->removeElement('parentcategory');
306                 }
307                 if ($mform->elementExists('currentparentaggregation')) {
308                     $mform->removeElement('currentparentaggregation');
309                 }
311             } else {
312                 // if we wanted to change parent of existing category - we would have to verify there are no circular references in parents!!!
313                 if ($mform->elementExists('parentcategory')) {
314                     $mform->hardFreeze('parentcategory');
315                 }
316                 $parent_cat = $grade_category->get_parent_category();
317                 $mform->setDefault('currentparentaggregation', $this->aggregation_options[$parent_cat->aggregation]);
319             }
321             if ($grade_item->is_calculated()) {
322                 // following elements are ignored when calculation formula used
323                 if ($mform->elementExists('aggregation')) {
324                     $mform->removeElement('aggregation');
325                 }
326                 if ($mform->elementExists('keephigh')) {
327                     $mform->removeElement('keephigh');
328                 }
329                 if ($mform->elementExists('droplow')) {
330                     $mform->removeElement('droplow');
331                 }
332                 if ($mform->elementExists('aggregateonlygraded')) {
333                     $mform->removeElement('aggregateonlygraded');
334                 }
335                 if ($mform->elementExists('aggregateoutcomes')) {
336                     $mform->removeElement('aggregateoutcomes');
337                 }
338                 if ($mform->elementExists('aggregatesubcats')) {
339                     $mform->removeElement('aggregatesubcats');
340                 }
341             }
343             // If it is a course category, remove the "required" rule from the "fullname" element
344             if ($grade_category->is_course_category()) {
345                 unset($mform->_rules['fullname']);
346                 $key = array_search('fullname', $mform->_required);
347                 unset($mform->_required[$key]);
348             }
350             // If it is a course category and its fullname is ?, show an empty field
351             if ($grade_category->is_course_category() && $mform->getElementValue('fullname') == '?') {
352                 $mform->setDefault('fullname', '');
353             }
354             // remove unwanted aggregation options
355             if ($mform->elementExists('aggregation')) {
356                 $allaggoptions = array_keys($this->aggregation_options);
357                 $agg_el =& $mform->getElement('aggregation');
358                 $visible = explode(',', $CFG->grade_aggregations_visible);
359                 if (!is_null($grade_category->aggregation)) {
360                     // current type is always visible
361                     $visible[] = $grade_category->aggregation;
362                 }
363                 foreach ($allaggoptions as $type) {
364                     if (!in_array($type, $visible)) {
365                         $agg_el->removeOption($type);
366                     }
367                 }
368             }
370         } else {
371             // adding new category
372             if ($mform->elementExists('currentparentaggregation')) {
373                 $mform->removeElement('currentparentaggregation');
374             }
375             // remove unwanted aggregation options
376             if ($mform->elementExists('aggregation')) {
377                 $allaggoptions = array_keys($this->aggregation_options);
378                 $agg_el =& $mform->getElement('aggregation');
379                 $visible = explode(',', $CFG->grade_aggregations_visible);
380                 foreach ($allaggoptions as $type) {
381                     if (!in_array($type, $visible)) {
382                         $agg_el->removeOption($type);
383                     }
384                 }
385             }
386         }
389         // no parent header for course category
390         if (!$mform->elementExists('parentcategory')) {
391             $mform->removeElement('headerparent');
392         }
394 /// GRADE ITEM
395         if ($id = $mform->getElementValue('id')) {
396             $grade_category = grade_category::fetch(array('id'=>$id));
397             $grade_item = $grade_category->load_grade_item();
399             $mform->setDefault('grade_item_hidden', (int) $grade_item->hidden);
401             if ($grade_item->is_outcome_item()) {
402                 // we have to prevent incompatible modifications of outcomes if outcomes disabled
403                 $mform->removeElement('grade_item_grademax');
404                 $mform->removeElement('grade_item_grademin');
405                 $mform->removeElement('grade_item_gradetype');
406                 $mform->removeElement('grade_item_display');
407                 $mform->removeElement('grade_item_decimals');
408                 $mform->hardFreeze('grade_item_scaleid');
409             }
411             //remove the aggregation coef element if not needed
412             if ($grade_item->is_course_item()) {
413                 if ($mform->elementExists('grade_item_aggregationcoef')) {
414                     $mform->removeElement('grade_item_aggregationcoef');
415                 }
417             } else {
418                 if ($grade_item->is_category_item()) {
419                     $category = $grade_item->get_item_category();
420                     $parent_category = $category->get_parent_category();
421                 } else {
422                     $parent_category = $grade_item->get_parent_category();
423                 }
425                 $parent_category->apply_forced_settings();
427                 if (!$parent_category->is_aggregationcoef_used()) {
428                     if ($mform->elementExists('grade_item_aggregationcoef')) {
429                         $mform->removeElement('grade_item_aggregationcoef');
430                     }
431                 } else {
433                     $coefstring = $grade_item->get_coefstring();
435                     if ($coefstring == 'aggregationcoefextrasum') {
436                         // advcheckbox is not compatible with disabledIf!
437                         $element =& $mform->createElement('checkbox', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
438                     } else {
439                         $element =& $mform->createElement('text', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
440                     }
441                     $mform->insertElementBefore($element, 'parentcategory');
442                     $mform->setHelpButton('grade_item_aggregationcoef', array($coefstring, get_string($coefstring, 'grades'), 'grade'), true);
443                 }
444             }
445         }
446     }
448 /// perform extra validation before submission
449     function validation($data, $files) {
450         global $COURSE;
452         $errors = parent::validation($data, $files);
454         if (array_key_exists('grade_item_gradetype', $data) and $data['grade_item_gradetype'] == GRADE_TYPE_SCALE) {
455             if (empty($data['grade_item_scaleid'])) {
456                 $errors['grade_item_scaleid'] = get_string('missingscale', 'grades');
457             }
458         }
459         if (array_key_exists('grade_item_grademin', $data) and array_key_exists('grade_item_grademax', $data)) {
460             if (($data['grade_item_grademax'] != 0 OR $data['grade_item_grademin'] != 0) AND
461                 ($data['grade_item_grademax'] == $data['grade_item_grademin'] OR
462                  $data['grade_item_grademax'] < $data['grade_item_grademin'])) {
463                  $errors['grade_item_grademin'] = get_string('incorrectminmax', 'grades');
464                  $errors['grade_item_grademax'] = get_string('incorrectminmax', 'grades');
465              }
466         }
468         return $errors;
469     }