Differences Between: [Versions 310 and 311] [Versions 311 and 403] [Versions 39 and 311]
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 /** 18 * A moodleform allowing the editing of the grade options for an individual grade item 19 * 20 * @package core_grades 21 * @copyright 2007 Petr Skoda 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 if (!defined('MOODLE_INTERNAL')) { 26 die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page 27 } 28 29 require_once $CFG->libdir.'/formslib.php'; 30 31 class edit_item_form extends moodleform { 32 private $displayoptions; 33 34 function definition() { 35 global $COURSE, $CFG, $DB; 36 37 $mform =& $this->_form; 38 39 $item = $this->_customdata['current']; 40 41 /// visible elements 42 $mform->addElement('header', 'general', get_string('gradeitem', 'grades')); 43 44 $mform->addElement('text', 'itemname', get_string('itemname', 'grades')); 45 $mform->setType('itemname', PARAM_TEXT); 46 $mform->addElement('text', 'iteminfo', get_string('iteminfo', 'grades')); 47 $mform->addHelpButton('iteminfo', 'iteminfo', 'grades'); 48 $mform->setType('iteminfo', PARAM_TEXT); 49 50 $mform->addElement('text', 'idnumber', get_string('idnumbermod')); 51 $mform->addHelpButton('idnumber', 'idnumbermod'); 52 $mform->setType('idnumber', PARAM_RAW); 53 54 if (!empty($item->id)) { 55 $gradeitem = new grade_item(array('id' => $item->id, 'courseid' => $item->courseid)); 56 // If grades exist set a message so the user knows why they can not alter the grade type or scale. 57 // We could never change the grade type for external items, so only need to show this for manual grade items. 58 if ($gradeitem->has_grades() && !$gradeitem->is_external_item()) { 59 // Set a message so the user knows why they can not alter the grade type or scale. 60 if ($gradeitem->gradetype == GRADE_TYPE_SCALE) { 61 $gradesexistmsg = get_string('modgradecantchangegradetyporscalemsg', 'grades'); 62 } else { 63 $gradesexistmsg = get_string('modgradecantchangegradetypemsg', 'grades'); 64 } 65 66 $gradesexisthtml = '<div class=\'alert\'>' . $gradesexistmsg . '</div>'; 67 $mform->addElement('static', 'gradesexistmsg', '', $gradesexisthtml); 68 } 69 } 70 71 // Manual grade items cannot have grade type GRADE_TYPE_NONE. 72 $options = array(GRADE_TYPE_VALUE => get_string('typevalue', 'grades'), 73 GRADE_TYPE_SCALE => get_string('typescale', 'grades'), 74 GRADE_TYPE_TEXT => get_string('typetext', 'grades')); 75 76 $mform->addElement('select', 'gradetype', get_string('gradetype', 'grades'), $options); 77 $mform->addHelpButton('gradetype', 'gradetype', 'grades'); 78 $mform->setDefault('gradetype', GRADE_TYPE_VALUE); 79 80 //$mform->addElement('text', 'calculation', get_string('calculation', 'grades')); 81 //$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT); 82 //$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE); 83 84 $options = array(0=>get_string('usenoscale', 'grades')); 85 if ($scales = grade_scale::fetch_all_local($COURSE->id)) { 86 foreach ($scales as $scale) { 87 $options[$scale->id] = $scale->get_name(); 88 } 89 } 90 if ($scales = grade_scale::fetch_all_global()) { 91 foreach ($scales as $scale) { 92 $options[$scale->id] = $scale->get_name(); 93 } 94 } 95 // ugly BC hack - it was possible to use custom scale from other courses :-( 96 if (!empty($item->scaleid) and !isset($options[$item->scaleid])) { 97 if ($scale = grade_scale::fetch(array('id'=>$item->scaleid))) { 98 $options[$scale->id] = $scale->get_name().get_string('incorrectcustomscale', 'grades'); 99 } 100 } 101 $mform->addElement('select', 'scaleid', get_string('scale'), $options); 102 $mform->addHelpButton('scaleid', 'typescale', 'grades'); 103 $mform->disabledIf('scaleid', 'gradetype', 'noteq', GRADE_TYPE_SCALE); 104 105 $choices = array(); 106 $choices[''] = get_string('choose'); 107 $choices['no'] = get_string('no'); 108 $choices['yes'] = get_string('yes'); 109 $mform->addElement('select', 'rescalegrades', get_string('modgraderescalegrades', 'grades'), $choices); 110 $mform->addHelpButton('rescalegrades', 'modgraderescalegrades', 'grades'); 111 $mform->disabledIf('rescalegrades', 'gradetype', 'noteq', GRADE_TYPE_VALUE); 112 113 $mform->addElement('float', 'grademax', get_string('grademax', 'grades')); 114 $mform->addHelpButton('grademax', 'grademax', 'grades'); 115 $mform->disabledIf('grademax', 'gradetype', 'noteq', GRADE_TYPE_VALUE); 116 117 if ((bool) get_config('moodle', 'grade_report_showmin')) { 118 $mform->addElement('float', 'grademin', get_string('grademin', 'grades')); 119 $mform->addHelpButton('grademin', 'grademin', 'grades'); 120 $mform->disabledIf('grademin', 'gradetype', 'noteq', GRADE_TYPE_VALUE); 121 } 122 123 $mform->addElement('float', 'gradepass', get_string('gradepass', 'grades')); 124 $mform->addHelpButton('gradepass', 'gradepass', 'grades'); 125 $mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_NONE); 126 $mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_TEXT); 127 128 $mform->addElement('float', 'multfactor', get_string('multfactor', 'grades')); 129 $mform->addHelpButton('multfactor', 'multfactor', 'grades'); 130 $mform->setAdvanced('multfactor'); 131 $mform->disabledIf('multfactor', 'gradetype', 'eq', GRADE_TYPE_NONE); 132 $mform->disabledIf('multfactor', 'gradetype', 'eq', GRADE_TYPE_TEXT); 133 134 $mform->addElement('float', 'plusfactor', get_string('plusfactor', 'grades')); 135 $mform->addHelpButton('plusfactor', 'plusfactor', 'grades'); 136 $mform->setAdvanced('plusfactor'); 137 $mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_NONE); 138 $mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_TEXT); 139 140 /// grade display prefs 141 $default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype); 142 $options = array(GRADE_DISPLAY_TYPE_DEFAULT => get_string('default', 'grades'), 143 GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'), 144 GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'), 145 GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'), 146 GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'), 147 GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'), 148 GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'), 149 GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'), 150 GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'), 151 GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades') 152 ); 153 154 asort($options); 155 156 foreach ($options as $key=>$option) { 157 if ($key == $default_gradedisplaytype) { 158 $options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option); 159 break; 160 } 161 } 162 $mform->addElement('select', 'display', get_string('gradedisplaytype', 'grades'), $options); 163 $mform->addHelpButton('display', 'gradedisplaytype', 'grades'); 164 $mform->disabledIf('display', 'gradetype', 'eq', GRADE_TYPE_TEXT); 165 166 $default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints); 167 $options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5); 168 $mform->addElement('select', 'decimals', get_string('decimalpoints', 'grades'), $options); 169 $mform->addHelpButton('decimals', 'decimalpoints', 'grades'); 170 $mform->setDefault('decimals', -1); 171 $mform->disabledIf('decimals', 'display', 'eq', GRADE_DISPLAY_TYPE_LETTER); 172 if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) { 173 $mform->disabledIf('decimals', 'display', "eq", GRADE_DISPLAY_TYPE_DEFAULT); 174 } 175 $mform->disabledIf('decimals', 'gradetype', 'eq', GRADE_TYPE_TEXT); 176 177 /// hiding 178 if ($item->cancontrolvisibility) { 179 $mform->addElement('advcheckbox', 'hidden', get_string('hidden', 'grades'), '', [], [0, 1]); 180 $mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true)); 181 $mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked'); 182 } else { 183 $mform->addElement('static', 'hidden', get_string('hidden', 'grades'), 184 get_string('componentcontrolsvisibility', 'grades')); 185 // Unset hidden to avoid data override. 186 unset($item->hidden); 187 } 188 $mform->addHelpButton('hidden', 'hidden', 'grades'); 189 190 /// locking 191 $mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades')); 192 $mform->addHelpButton('locked', 'locked', 'grades'); 193 194 $mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true)); 195 $mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE); 196 197 /// parent category related settings 198 $mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades')); 199 200 $mform->addElement('advcheckbox', 'weightoverride', get_string('adjustedweight', 'grades')); 201 $mform->addHelpButton('weightoverride', 'weightoverride', 'grades'); 202 $mform->disabledIf('weightoverride', 'gradetype', 'eq', GRADE_TYPE_NONE); 203 $mform->disabledIf('weightoverride', 'gradetype', 'eq', GRADE_TYPE_TEXT); 204 205 $mform->addElement('float', 'aggregationcoef2', get_string('weight', 'grades')); 206 $mform->addHelpButton('aggregationcoef2', 'weight', 'grades'); 207 $mform->disabledIf('aggregationcoef2', 'weightoverride'); 208 $mform->disabledIf('aggregationcoef2', 'gradetype', 'eq', GRADE_TYPE_NONE); 209 $mform->disabledIf('aggregationcoef2', 'gradetype', 'eq', GRADE_TYPE_TEXT); 210 211 $options = array(); 212 $coefstring = ''; 213 $categories = grade_category::fetch_all(array('courseid'=>$COURSE->id)); 214 215 foreach ($categories as $cat) { 216 $cat->apply_forced_settings(); 217 $options[$cat->id] = $cat->get_name(); 218 } 219 220 if (count($categories) > 1) { 221 $mform->addElement('select', 'parentcategory', get_string('gradecategory', 'grades'), $options); 222 } 223 224 /// hidden params 225 $mform->addElement('hidden', 'id', 0); 226 $mform->setType('id', PARAM_INT); 227 228 $mform->addElement('hidden', 'courseid', $COURSE->id); 229 $mform->setType('courseid', PARAM_INT); 230 231 $mform->addElement('hidden', 'itemtype', 'manual'); // all new items are manual only 232 $mform->setType('itemtype', PARAM_ALPHA); 233 234 /// add return tracking info 235 $gpr = $this->_customdata['gpr']; 236 $gpr->add_mform_elements($mform); 237 238 /// mark advanced according to site settings 239 if (isset($CFG->grade_item_advanced)) { 240 $advanced = explode(',', $CFG->grade_item_advanced); 241 foreach ($advanced as $el) { 242 if ($mform->elementExists($el)) { 243 $mform->setAdvanced($el); 244 } 245 } 246 } 247 //------------------------------------------------------------------------------- 248 // buttons 249 $this->add_action_buttons(); 250 //------------------------------------------------------------------------------- 251 $this->set_data($item); 252 } 253 254 255 /// tweak the form - depending on existing data 256 function definition_after_data() { 257 global $CFG, $COURSE; 258 259 $mform =& $this->_form; 260 261 if ($id = $mform->getElementValue('id')) { 262 $gradeitem = grade_item::fetch(array('id' => $id)); 263 $parentcategory = $gradeitem->get_parent_category(); 264 } else { 265 // If we do not have an id, we are creating a new grade item. 266 $gradeitem = new grade_item(array('courseid' => $COURSE->id, 'itemtype' => 'manual'), false); 267 268 // Assign the course category to this grade item. 269 $parentcategory = grade_category::fetch_course_category($COURSE->id); 270 $gradeitem->parent_category = $parentcategory; 271 } 272 273 if (!$gradeitem->is_raw_used()) { 274 $mform->removeElement('plusfactor'); 275 $mform->removeElement('multfactor'); 276 } 277 278 if ($gradeitem->is_outcome_item()) { 279 // We have to prevent incompatible modifications of outcomes if outcomes disabled. 280 $mform->removeElement('grademax'); 281 if ($mform->elementExists('grademin')) { 282 $mform->removeElement('grademin'); 283 } 284 $mform->removeElement('gradetype'); 285 $mform->removeElement('display'); 286 $mform->removeElement('decimals'); 287 $mform->hardFreeze('scaleid'); 288 289 } else { 290 if ($gradeitem->is_external_item()) { 291 // Following items are set up from modules and should not be overrided by user. 292 if ($mform->elementExists('grademin')) { 293 // The site setting grade_report_showmin may have prevented grademin being added to the form. 294 $mform->hardFreeze('grademin'); 295 } 296 $mform->hardFreeze('itemname,gradetype,grademax,scaleid'); 297 if ($gradeitem->itemnumber == 0) { 298 // The idnumber of grade itemnumber 0 is synced with course_modules. 299 $mform->hardFreeze('idnumber'); 300 } 301 302 // For external items we can not change the grade type, even if no grades exist, so if it is set to 303 // scale, then remove the grademax and grademin fields from the form - no point displaying them. 304 if ($gradeitem->gradetype == GRADE_TYPE_SCALE) { 305 $mform->removeElement('grademax'); 306 if ($mform->elementExists('grademin')) { 307 $mform->removeElement('grademin'); 308 } 309 } else { // Not using scale, so remove it. 310 $mform->removeElement('scaleid'); 311 } 312 313 // Always remove the rescale grades element if it's an external item. 314 $mform->removeElement('rescalegrades'); 315 } else if ($gradeitem->has_grades()) { 316 // Can't change the grade type or the scale if there are grades. 317 $mform->hardFreeze('gradetype, scaleid'); 318 319 // If we are using scales then remove the unnecessary rescale and grade fields. 320 if ($gradeitem->gradetype == GRADE_TYPE_SCALE) { 321 $mform->removeElement('rescalegrades'); 322 $mform->removeElement('grademax'); 323 if ($mform->elementExists('grademin')) { 324 $mform->removeElement('grademin'); 325 } 326 } else { // Remove the scale field. 327 $mform->removeElement('scaleid'); 328 // Set the maximum grade to disabled unless a grade is chosen. 329 $mform->disabledIf('grademax', 'rescalegrades', 'eq', ''); 330 } 331 } else { 332 // Remove the rescale element if there are no grades. 333 $mform->removeElement('rescalegrades'); 334 } 335 } 336 337 // If we wanted to change parent of existing item - we would have to verify there are no circular references in parents!!! 338 if ($id && $mform->elementExists('parentcategory')) { 339 $mform->hardFreeze('parentcategory'); 340 } 341 342 $parentcategory->apply_forced_settings(); 343 344 if (!$parentcategory->is_aggregationcoef_used()) { 345 if ($mform->elementExists('aggregationcoef')) { 346 $mform->removeElement('aggregationcoef'); 347 } 348 349 } else { 350 $coefstring = $gradeitem->get_coefstring(); 351 352 if ($coefstring !== '') { 353 if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') { 354 // The advcheckbox is not compatible with disabledIf! 355 $coefstring = 'aggregationcoefextrasum'; 356 $element =& $mform->createElement('checkbox', 'aggregationcoef', get_string($coefstring, 'grades')); 357 } else { 358 $element =& $mform->createElement('text', 'aggregationcoef', get_string($coefstring, 'grades')); 359 } 360 if ($mform->elementExists('parentcategory')) { 361 $mform->insertElementBefore($element, 'parentcategory'); 362 } else { 363 $mform->insertElementBefore($element, 'id'); 364 } 365 $mform->addHelpButton('aggregationcoef', $coefstring, 'grades'); 366 } 367 $mform->disabledIf('aggregationcoef', 'gradetype', 'eq', GRADE_TYPE_NONE); 368 $mform->disabledIf('aggregationcoef', 'gradetype', 'eq', GRADE_TYPE_TEXT); 369 $mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $parentcategory->id); 370 } 371 372 // Remove fields used by natural weighting if the parent category is not using natural weighting. 373 // Or if the item is a scale and scales are not used in aggregation. 374 if ($parentcategory->aggregation != GRADE_AGGREGATE_SUM 375 || (empty($CFG->grade_includescalesinaggregation) && $gradeitem->gradetype == GRADE_TYPE_SCALE)) { 376 if ($mform->elementExists('weightoverride')) { 377 $mform->removeElement('weightoverride'); 378 } 379 if ($mform->elementExists('aggregationcoef2')) { 380 $mform->removeElement('aggregationcoef2'); 381 } 382 } 383 384 if ($category = $gradeitem->get_item_category()) { 385 if ($category->aggregation == GRADE_AGGREGATE_SUM) { 386 if ($mform->elementExists('gradetype')) { 387 $mform->hardFreeze('gradetype'); 388 } 389 if ($mform->elementExists('grademin')) { 390 $mform->hardFreeze('grademin'); 391 } 392 if ($mform->elementExists('grademax')) { 393 $mform->hardFreeze('grademax'); 394 } 395 if ($mform->elementExists('scaleid')) { 396 $mform->removeElement('scaleid'); 397 } 398 } 399 } 400 401 // no parent header for course category 402 if (!$mform->elementExists('aggregationcoef') and !$mform->elementExists('parentcategory')) { 403 $mform->removeElement('headerparent'); 404 } 405 } 406 407 /// perform extra validation before submission 408 function validation($data, $files) { 409 global $COURSE; 410 $grade_item = false; 411 if ($data['id']) { 412 $grade_item = new grade_item(array('id' => $data['id'], 'courseid' => $data['courseid'])); 413 } 414 415 $errors = parent::validation($data, $files); 416 417 if (array_key_exists('idnumber', $data)) { 418 if ($grade_item) { 419 if ($grade_item->itemtype == 'mod') { 420 $cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid); 421 } else { 422 $cm = null; 423 } 424 } else { 425 $grade_item = null; 426 $cm = null; 427 } 428 if (!grade_verify_idnumber($data['idnumber'], $COURSE->id, $grade_item, $cm)) { 429 $errors['idnumber'] = get_string('idnumbertaken'); 430 } 431 } 432 433 if (array_key_exists('gradetype', $data) and $data['gradetype'] == GRADE_TYPE_SCALE) { 434 if (empty($data['scaleid'])) { 435 $errors['scaleid'] = get_string('missingscale', 'grades'); 436 } 437 } 438 439 // We need to make all the validations related with grademax and grademin 440 // with them being correct floats, keeping the originals unmodified for 441 // later validations / showing the form back... 442 // TODO: Note that once MDL-73994 is fixed we'll have to re-visit this and 443 // adapt the code below to the new values arriving here, without forgetting 444 // the special case of empties and nulls. 445 $grademax = isset($data['grademax']) ? unformat_float($data['grademax']) : null; 446 $grademin = isset($data['grademin']) ? unformat_float($data['grademin']) : null; 447 448 if (!is_null($grademin) and !is_null($grademax)) { 449 if ($grademax == $grademin or $grademax < $grademin) { 450 $errors['grademin'] = get_string('incorrectminmax', 'grades'); 451 $errors['grademax'] = get_string('incorrectminmax', 'grades'); 452 } 453 } 454 455 // We do not want the user to be able to change the grade type or scale for this item if grades exist. 456 if ($grade_item && $grade_item->has_grades()) { 457 // Check that grade type is set - should never not be set unless form has been modified. 458 if (!isset($data['gradetype'])) { 459 $errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades'); 460 } else if ($data['gradetype'] !== $grade_item->gradetype) { // Check if we are changing the grade type. 461 $errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades'); 462 } else if ($data['gradetype'] == GRADE_TYPE_SCALE) { 463 // Check if we are changing the scale - can't do this when grades exist. 464 if (isset($data['scaleid']) && ($data['scaleid'] !== $grade_item->scaleid)) { 465 $errors['scaleid'] = get_string('modgradecantchangescale', 'grades'); 466 } 467 } 468 } 469 if ($grade_item) { 470 if ($grade_item->gradetype == GRADE_TYPE_VALUE) { 471 if ((((bool) get_config('moodle', 'grade_report_showmin')) && 472 grade_floats_different($grademin, $grade_item->grademin)) || 473 grade_floats_different($grademax, $grade_item->grademax)) { 474 if ($grade_item->has_grades() && empty($data['rescalegrades'])) { 475 $errors['rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades'); 476 } 477 } 478 } 479 } 480 481 return $errors; 482 } 483 484 } 485
title
Description
Body
title
Description
Body
title
Description
Body
title
Body