first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+146
View File
@@ -0,0 +1,146 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Performs actions on grade items and categories like hiding and locking
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
$courseid = required_param('id', PARAM_INT);
$action = required_param('action', PARAM_ALPHA);
$eid = required_param('eid', PARAM_ALPHANUM);
$PAGE->set_url('/grade/edit/tree/action.php', array('id'=>$courseid, 'action'=>$action, 'eid'=>$eid));
/// Make sure they can even access this course
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/edit/tree/index.php?id='.$course->id);
// get the grading tree object
$gtree = new grade_tree($courseid, false, false);
// what are we working with?
if (!$element = $gtree->locate_element($eid)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$object = $element['object'];
$type = $element['type'];
switch ($action) {
case 'hide':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
throw new \moodle_exception('nopermissiontohide', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
if (!$object->can_control_visibility()) {
throw new \moodle_exception('componentcontrolsvisibility', 'grades', $returnurl);
}
$object->set_hidden(1, true);
}
break;
case 'show':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
throw new \moodle_exception('nopermissiontoshow', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
if (!$object->can_control_visibility()) {
throw new \moodle_exception('componentcontrolsvisibility', 'grades', $returnurl);
}
$object->set_hidden(0, true);
}
break;
case 'lock':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context)) {
throw new \moodle_exception('nopermissiontolock', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
$object->set_locked(1, false, true);
}
break;
case 'unlock':
if ($eid and confirm_sesskey()) {
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context)) {
throw new \moodle_exception('nopermissiontounlock', '', $returnurl);
}
if ($type == 'grade' and empty($object->id)) {
$object->insert();
}
$object->set_locked(0, false, true);
}
break;
case 'resetweights':
if ($eid && confirm_sesskey()) {
// This is specific to category items with natural weight as an aggregation method, and can
// only be done by someone who can manage the grades.
if ($type != 'category' || $object->aggregation != GRADE_AGGREGATE_SUM ||
!has_capability('moodle/grade:manage', $context)) {
throw new \moodle_exception('nopermissiontoresetweights', 'grades', $returnurl);
}
// Remove the weightoverride flag from the children.
$children = $object->get_children();
foreach ($children as $item) {
if ($item['type'] == 'category') {
$gradeitem = $item['object']->load_grade_item();
} else {
$gradeitem = $item['object'];
}
if ($gradeitem->weightoverride == false) {
continue;
}
$gradeitem->weightoverride = false;
$gradeitem->update();
}
// Force regrading.
$object->force_regrading();
}
}
redirect($returnurl);
//redirect($returnurl, 'debug delay', 5);
+220
View File
@@ -0,0 +1,220 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Edit a calculated grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->libdir.'/mathslib.php';
require_once 'calculation_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = required_param('id', PARAM_INT);
$section = optional_param('section', 'calculation', PARAM_ALPHA);
$idnumbers = optional_param_array('idnumbers', null, PARAM_RAW);
$url = new moodle_url('/grade/edit/tree/calculation.php', array('id'=>$id, 'courseid'=>$courseid));
if ($section !== 'calculation') {
$url->param('section', $section);
}
$PAGE->set_url($url);
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$course->id)));
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report/index.php?id='.$course->id);
if (!$grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
throw new \moodle_exception('invaliditemid');
}
// activity items and items without grade can not have calculation
if ($grade_item->is_external_item() or ($grade_item->gradetype != GRADE_TYPE_VALUE and $grade_item->gradetype != GRADE_TYPE_SCALE)) {
redirect($returnurl, get_string('errornocalculationallowed', 'grades'));
}
$mform = new edit_calculation_form(null, array('gpr'=>$gpr, 'itemid' => $grade_item->id));
if ($mform->is_cancelled()) {
redirect($returnurl);
}
$calculation = calc_formula::localize($grade_item->calculation);
$calculation = grade_item::denormalize_formula($calculation, $grade_item->courseid);
$mform->set_data(array('courseid'=>$grade_item->courseid, 'calculation'=>$calculation, 'id'=>$grade_item->id, 'itemname'=>$grade_item->itemname));
$errors = array();
if ($data = $mform->get_data()) {
$calculation = calc_formula::unlocalize($data->calculation);
$grade_item->set_calculation($calculation);
redirect($returnurl);
} elseif (!empty($section) AND $section='idnumbers' AND !empty($idnumbers)) { // Handle idnumbers separately (non-mform)
//first validate and store the new idnumbers
foreach ($idnumbers as $giid => $value) {
if ($gi = grade_item::fetch(array('id' => $giid))) {
if ($gi->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($gi->itemmodule, $gi->iteminstance, $gi->courseid);
} else {
$cm = null;
}
if (!grade_verify_idnumber($value, $COURSE->id, $gi, $cm)) {
$errors[$giid] = get_string('idnumbertaken');
continue;
}
if (empty($gi->idnumber) and !$gi->add_idnumber($idnumbers[$gi->id])) {
$errors[$giid] = get_string('error');
continue;
}
} else {
$errors[$giid] = 'Could not fetch the grade_item with id=' . $giid;
}
}
}
$gtree = new grade_tree($course->id, false, false);
$strgrades = get_string('grades');
$strgraderreport = get_string('graderreport', 'grades');
$strcalculationedit = get_string('editcalculation', 'grades');
$PAGE->navbar->add($strcalculationedit);
print_grade_page_head($courseid, 'settings', null, $strcalculationedit, false, false, false);
$mform->display();
// Now show the gradetree with the idnumbers add/edit form
echo '
<form class="mform" id="mform2" method="post" action="' . $CFG->wwwroot . '/grade/edit/tree/calculation.php?courseid='.$courseid.'&amp;id='.$id.'">
<div style="display: none;">
<input type="hidden" value="'.$id.'" name="id"/>
<input type="hidden" value="'.$courseid.'" name="courseid"/>
<input type="hidden" value="'.$gpr->type.'" name="gpr_type"/>
<input type="hidden" value="'.$gpr->plugin.'" name="gpr_plugin"/>
<input type="hidden" value="'.$gpr->courseid.'" name="gpr_courseid"/>
<input type="hidden" value="'.sesskey().'" name="sesskey"/>
<input type="hidden" value="idnumbers" name="section"/>
</div>
<fieldset id="idnumbers" class="clearfix">
<legend class="ftoggler">'.get_string('idnumbers', 'grades').'</legend>
<div class="fcontainer clearfix">
<ul>
' . get_grade_tree($gtree, $gtree->top_element, $id, $errors) . '
</ul>
</div>
</fieldset>
<div class="fitem" style="text-align: center;">
<input id="id_addidnumbers" type="submit" class="btn btn-secondary" value="' . get_string('addidnumbers', 'grades') . '" name="addidnumbers" />
</div>
</form>';
echo $OUTPUT->footer();
die();
/**
* Simplified version of the print_grade_tree() recursive function found in grade/edit/tree/index.php
* Only prints a tree with a basic icon for each element, and an edit field for
* items without an idnumber.
* @param object $gtree
* @param object $element
* @param int $current_itemid The itemid of this page: should be excluded from the tree
* @param array $errors An array of idnumbers => error
* @return string
*/
function get_grade_tree(&$gtree, $element, $current_itemid=null, $errors=null) {
global $CFG;
$object = $element['object'];
$eid = $element['eid'];
$type = $element['type'];
$grade_item = $object->get_grade_item();
$name = $object->get_name();
$return_string = '';
//TODO: improve outcome visualisation
if ($type == 'item' and !empty($object->outcomeid)) {
$name = $name.' ('.get_string('outcome', 'grades').')';
}
$idnumber = $object->get_idnumber();
// Don't show idnumber or input field for current item if given to function. Highlight the item instead.
if ($type != 'category') {
if (is_null($current_itemid) OR $grade_item->id != $current_itemid) {
if ($idnumber) {
$name .= ": [[$idnumber]]";
} else {
$closingdiv = '';
if (!empty($errors[$grade_item->id])) {
$name .= '<div class="error"><span class="error">' . $errors[$grade_item->id].'</span><br />'."\n";
$closingdiv = "</div>\n";
}
$name .= '<label class="accesshide" for="id_idnumber_' . $grade_item->id . '">' . get_string('gradeitems', 'grades') .'</label>';
$name .= '<input class="idnumber" id="id_idnumber_'.$grade_item->id.'" type="text" name="idnumbers['.$grade_item->id.']" />' . "\n";
$name .= $closingdiv;
}
} else {
$name = "<strong>$name</strong>";
}
}
$icon = grade_helper::get_element_icon($element, true);
$last = '';
$catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
if ($type != 'category') {
$return_string .= '<li class="'.$type.'">'.$icon.$name.'</li>' . "\n";
} else {
$return_string .= '<li class="'.$type.'">'.$icon.$name . "\n";
$return_string .= '<ul class="catlevel'.$element['depth'].'">'."\n";
$last = null;
foreach($element['children'] as $child_el) {
$return_string .= get_grade_tree($gtree, $child_el, $current_itemid, $errors);
}
if ($last) {
$return_string .= get_grade_tree($gtree, $last, $current_itemid, $errors);
}
$return_string .= '</ul></li>'."\n";
}
return $return_string;
}
+108
View File
@@ -0,0 +1,108 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A moodleform to allow the editing of a calculated grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_calculation_form extends moodleform {
public $available;
public $noidnumbers;
function definition() {
global $COURSE;
$mform =& $this->_form;
$itemid = $this->_customdata['itemid'];
$this->available = grade_item::fetch_all(array('courseid'=>$COURSE->id));
$this->noidnumbers = array();
// All items that have no idnumbers are added to a separate section of the form (hidden by default),
// enabling the user to assign idnumbers to these grade_items.
foreach ($this->available as $item) {
if (empty($item->idnumber)) {
$this->noidnumbers[$item->id] = $item;
unset($this->available[$item->id]);
}
if ($item->id == $itemid) { // Do not include the current grade_item in the available section
unset($this->available[$item->id]);
}
}
/// visible elements
$mform->addElement('header', 'general', get_string('gradeitem', 'grades'));
$mform->addElement('static', 'itemname', get_string('itemname', 'grades'));
$mform->addElement('textarea', 'calculation', get_string('calculation', 'grades'), 'cols="60" rows="5"');
$mform->addHelpButton('calculation', 'calculation', 'grades');
$mform->setForceLtr('calculation');
/// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', 0);
$mform->setType('courseid', PARAM_INT);
$mform->addElement('hidden', 'section', 0);
$mform->setType('section', PARAM_ALPHA);
$mform->setDefault('section', 'calculation');
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
$this->add_action_buttons();
}
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
}
/// perform extra validation before submission
function validation($data, $files) {
$errors = parent::validation($data, $files);
$mform =& $this->_form;
// check the calculation formula
if ($data['calculation'] != '') {
$grade_item = grade_item::fetch(array('id'=>$data['id'], 'courseid'=>$data['courseid']));
$calculation = calc_formula::unlocalize(stripslashes($data['calculation']));
$result = $grade_item->validate_formula($calculation);
if ($result !== true) {
$errors['calculation'] = $result;
}
}
return $errors;
}
}
+155
View File
@@ -0,0 +1,155 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Edit the grade options for an individual grade category
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_grades\form\add_category;
require_once('../../../config.php');
require_once($CFG->dirroot.'/grade/lib.php');
require_once($CFG->dirroot.'/grade/edit/tree/lib.php');
require_once($CFG->dirroot.'/grade/report/lib.php');
require_once('category_form.php');
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT); // grade_category->id
$url = new moodle_url('/grade/edit/tree/category.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$courseid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$course->id);
$heading = get_string('categoryedit', 'grades');
if ($id) {
if (!$grade_category = grade_category::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
throw new \moodle_exception('invalidcategory');
}
$grade_category->apply_forced_settings();
$category = $grade_category->get_record_data();
// set parent
$category->parentcategory = $grade_category->parent;
$grade_item = $grade_category->load_grade_item();
// nomalize coef values if needed
$parent_category = $grade_category->get_parent_category();
foreach ($grade_item->get_record_data() as $key => $value) {
$category->{"grade_item_$key"} = $value;
}
$decimalpoints = $grade_item->get_decimals();
$category->grade_item_grademax = format_float($category->grade_item_grademax, $decimalpoints);
$category->grade_item_grademin = format_float($category->grade_item_grademin, $decimalpoints);
$category->grade_item_gradepass = format_float($category->grade_item_gradepass, $decimalpoints);
$category->grade_item_multfactor = format_float($category->grade_item_multfactor, 4);
$category->grade_item_plusfactor = format_float($category->grade_item_plusfactor, 4);
$category->grade_item_aggregationcoef2 = format_float($category->grade_item_aggregationcoef2 * 100.0, 4);
if (!$parent_category) {
// keep as is
} else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM or $parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$category->grade_item_aggregationcoef = $category->grade_item_aggregationcoef == 0 ? 0 : 1;
} else {
$category->grade_item_aggregationcoef = format_float($category->grade_item_aggregationcoef, 4);
}
// Check to see if the gradebook is frozen. This allows grades to not be altered at all until a user verifies that they
// wish to update the grades.
$gradebookcalculationsfreeze = get_config('core', 'gradebook_calculations_freeze_' . $courseid);
// Stick with the original code if the grade book is frozen.
if ($gradebookcalculationsfreeze && (int)$gradebookcalculationsfreeze <= 20150627) {
if ($category->aggregation == GRADE_AGGREGATE_SUM) {
// Input fields for grademin and grademax are disabled for the "Natural" category,
// this means they will be ignored if user does not change aggregation method.
// But if user does change aggregation method the default values should be used.
$category->grademax = 100;
$category->grade_item_grademax = 100;
$category->grademin = 0;
$category->grade_item_grademin = 0;
}
} else {
if ($category->aggregation == GRADE_AGGREGATE_SUM && !$grade_item->is_calculated()) {
// Input fields for grademin and grademax are disabled for the "Natural" category,
// this means they will be ignored if user does not change aggregation method.
// But if user does change aggregation method the default values should be used.
// This does not apply to calculated category totals.
$category->grademax = 100;
$category->grade_item_grademax = 100;
$category->grademin = 0;
$category->grade_item_grademin = 0;
}
}
} else {
$heading = get_string('newcategory', 'grades');
$grade_category = new grade_category(array('courseid'=>$courseid), false);
$grade_category->apply_default_settings();
$grade_category->apply_forced_settings();
$category = $grade_category->get_record_data();
$grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
foreach ($grade_item->get_record_data() as $key => $value) {
$category->{"grade_item_$key"} = $value;
}
}
$mform = new edit_category_form(null, array('current'=>$category, 'gpr'=>$gpr));
$simpleform = new add_category(null, ['category' => $grade_category->id, 'courseid' => $courseid, 'gpr' => $gpr]);
// Data has been carried over from the dynamic form.
if ($simpledata = $simpleform->get_submitted_data()) {
$mform->set_data($simpledata);
}
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
grade_edit_tree::update_gradecategory($grade_category, $data);
redirect($returnurl);
}
$PAGE->navbar->add($heading);
print_grade_page_head($courseid, 'settings', null, $heading, false, false, false);
$mform->display();
echo $OUTPUT->footer();
die;
+554
View File
@@ -0,0 +1,554 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A moodleform to edit the grade options for an individual grade category
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_category_form extends moodleform {
private $aggregation_options = array();
function definition() {
global $CFG, $COURSE, $DB, $OUTPUT;
$mform =& $this->_form;
$category = $this->_customdata['current'];
$this->aggregation_options = grade_helper::get_aggregation_strings();
// visible elements
$mform->addElement('header', 'headercategory', get_string('gradecategory', 'grades'));
$mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
$mform->setType('fullname', PARAM_TEXT);
$mform->addRule('fullname', null, 'required', null, 'client');
$mform->addElement('select', 'aggregation', get_string('aggregation', 'grades'), $this->aggregation_options);
$mform->addHelpButton('aggregation', 'aggregation', 'grades');
$mform->addElement('checkbox', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades'));
$mform->addHelpButton('aggregateonlygraded', 'aggregateonlygraded', 'grades');
if (empty($CFG->enableoutcomes)) {
$mform->addElement('hidden', 'aggregateoutcomes');
$mform->setType('aggregateoutcomes', PARAM_INT);
} else {
$mform->addElement('checkbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
$mform->addHelpButton('aggregateoutcomes', 'aggregateoutcomes', 'grades');
}
$mform->addElement('text', 'keephigh', get_string('keephigh', 'grades'), 'size="3"');
$mform->setType('keephigh', PARAM_INT);
$mform->addHelpButton('keephigh', 'keephigh', 'grades');
$mform->addElement('text', 'droplow', get_string('droplow', 'grades'), 'size="3"');
$mform->setType('droplow', PARAM_INT);
$mform->addHelpButton('droplow', 'droplow', 'grades');
$mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
$mform->disabledIf('keephigh', 'droplow', 'noteq', 0);
$mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
// Grade item settings
// Displayed as Category total to avoid confusion between grade items requiring marking and category totals
$mform->addElement('header', 'general', get_string('categorytotal', 'grades'));
$mform->setExpanded('general');
$mform->addElement('text', 'grade_item_itemname', get_string('categorytotalname', 'grades'));
$mform->setType('grade_item_itemname', PARAM_TEXT);
$mform->addElement('text', 'grade_item_iteminfo', get_string('iteminfo', 'grades'));
$mform->addHelpButton('grade_item_iteminfo', 'iteminfo', 'grades');
$mform->setType('grade_item_iteminfo', PARAM_TEXT);
$mform->addElement('text', 'grade_item_idnumber', get_string('idnumbermod'));
$mform->addHelpButton('grade_item_idnumber', 'idnumbermod');
$mform->setType('grade_item_idnumber', PARAM_RAW);
if (!empty($category->id)) {
$gradecategory = grade_category::fetch(array('id' => $category->id));
$gradeitem = $gradecategory->load_grade_item();
// If grades exist set a message so the user knows why they can not alter the grade type or scale.
// We could never change the grade type for external items, so only need to show this for manual grade items.
if ($gradeitem->has_overridden_grades()) {
// Set a message so the user knows why the can not alter the grade type or scale.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$gradesexistmsg = get_string('modgradecategorycantchangegradetyporscalemsg', 'grades');
} else {
$gradesexistmsg = get_string('modgradecategorycantchangegradetypemsg', 'grades');
}
$notification = new \core\output\notification($gradesexistmsg, \core\output\notification::NOTIFY_INFO);
$notification->set_show_closebutton(false);
$mform->addElement('static', 'gradesexistmsg', '', $OUTPUT->render($notification));
}
}
$options = array(GRADE_TYPE_NONE=>get_string('typenone', 'grades'),
GRADE_TYPE_VALUE=>get_string('typevalue', 'grades'),
GRADE_TYPE_SCALE=>get_string('typescale', 'grades'),
GRADE_TYPE_TEXT=>get_string('typetext', 'grades'));
$mform->addElement('select', 'grade_item_gradetype', get_string('gradetype', 'grades'), $options);
$mform->addHelpButton('grade_item_gradetype', 'gradetype', 'grades');
$mform->setDefault('grade_item_gradetype', GRADE_TYPE_VALUE);
$mform->disabledIf('grade_item_gradetype', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
//$mform->addElement('text', 'calculation', get_string('calculation', 'grades'));
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT);
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE);
$options = array(0=>get_string('usenoscale', 'grades'));
if ($scales = grade_scale::fetch_all_local($COURSE->id)) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
if ($scales = grade_scale::fetch_all_global()) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
// ugly BC hack - it was possible to use custom scale from other courses :-(
if (!empty($category->grade_item_scaleid) and !isset($options[$category->grade_item_scaleid])) {
if ($scale = grade_scale::fetch(array('id'=>$category->grade_item_scaleid))) {
$options[$scale->id] = $scale->get_name().' '.get_string('incorrectcustomscale', 'grades');
}
}
$mform->addElement('select', 'grade_item_scaleid', get_string('scale'), $options);
$mform->addHelpButton('grade_item_scaleid', 'typescale', 'grades');
$mform->disabledIf('grade_item_scaleid', 'grade_item_gradetype', 'noteq', GRADE_TYPE_SCALE);
$mform->disabledIf('grade_item_scaleid', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
$choices = array();
$choices[''] = get_string('choose');
$choices['no'] = get_string('no');
$choices['yes'] = get_string('yes');
$mform->addElement('select', 'grade_item_rescalegrades', get_string('modgradecategoryrescalegrades', 'grades'), $choices);
$mform->addHelpButton('grade_item_rescalegrades', 'modgradecategoryrescalegrades', 'grades');
$mform->disabledIf('grade_item_rescalegrades', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->addElement('float', 'grade_item_grademax', get_string('grademax', 'grades'));
$mform->addHelpButton('grade_item_grademax', 'grademax', 'grades');
$mform->disabledIf('grade_item_grademax', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->disabledIf('grade_item_grademax', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
if ((bool) get_config('moodle', 'grade_report_showmin')) {
$mform->addElement('float', 'grade_item_grademin', get_string('grademin', 'grades'));
$mform->addHelpButton('grade_item_grademin', 'grademin', 'grades');
$mform->disabledIf('grade_item_grademin', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->disabledIf('grade_item_grademin', 'aggregation', 'eq', GRADE_AGGREGATE_SUM);
}
$mform->addElement('float', 'grade_item_gradepass', get_string('gradepass', 'grades'));
$mform->addHelpButton('grade_item_gradepass', 'gradepass', 'grades');
$mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_TEXT);
/// grade display prefs
$default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype);
$options = array(GRADE_DISPLAY_TYPE_DEFAULT => get_string('default', 'grades'),
GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'),
GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'),
GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades')
);
asort($options);
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
break;
}
}
$mform->addElement('select', 'grade_item_display', get_string('gradedisplaytype', 'grades'), $options);
$mform->addHelpButton('grade_item_display', 'gradedisplaytype', 'grades');
$mform->disabledIf('grade_item_display', 'grade_item_gradetype', 'in',
array(GRADE_TYPE_TEXT, GRADE_TYPE_NONE));
$default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints);
$options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
$mform->addElement('select', 'grade_item_decimals', get_string('decimalpoints', 'grades'), $options);
$mform->addHelpButton('grade_item_decimals', 'decimalpoints', 'grades');
$mform->setDefault('grade_item_decimals', -1);
$mform->disabledIf('grade_item_decimals', 'grade_item_display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
$mform->disabledIf('grade_item_decimals', 'grade_item_gradetype', 'in',
array(GRADE_TYPE_TEXT, GRADE_TYPE_NONE));
if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
$mform->disabledIf('grade_item_decimals', 'grade_item_display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
}
/// hiding
// advcheckbox is not compatible with disabledIf!
$mform->addElement('checkbox', 'grade_item_hidden', get_string('hidden', 'grades'));
$mform->addHelpButton('grade_item_hidden', 'hidden', 'grades');
$mform->addElement('date_time_selector', 'grade_item_hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('grade_item_hidden', 'grade_item_hiddenuntil[enabled]', 'checked');
/// locking
$mform->addElement('checkbox', 'grade_item_locked', get_string('locked', 'grades'));
$mform->addHelpButton('grade_item_locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'grade_item_locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('grade_item_locktime', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
/// parent category related settings
$mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
$mform->setExpanded('headerparent');
$mform->addElement('advcheckbox', 'grade_item_weightoverride', get_string('adjustedweight', 'grades'));
$mform->addHelpButton('grade_item_weightoverride', 'weightoverride', 'grades');
$mform->addElement('float', 'grade_item_aggregationcoef2', get_string('weight', 'grades'));
$mform->addHelpButton('grade_item_aggregationcoef2', 'weight', 'grades');
$mform->disabledIf('grade_item_aggregationcoef2', 'grade_item_weightoverride');
$options = array();
$default = -1;
$categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
foreach ($categories as $cat) {
$cat->apply_forced_settings();
$options[$cat->id] = $cat->get_name();
if ($cat->is_course_category()) {
$default = $cat->id;
}
}
if (count($categories) > 1) {
$mform->addElement('select', 'parentcategory', get_string('parentcategory', 'grades'), $options);
$mform->setDefault('parentcategory', $default);
$mform->addElement('static', 'currentparentaggregation', get_string('currentparentaggregation', 'grades'));
}
// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', 0);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
//-------------------------------------------------------------------------------
$this->set_data($category);
}
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
$somecat = new grade_category();
foreach ($somecat->forceable as $property) {
if ((int)$CFG->{"grade_{$property}_flag"} & 1) {
if ($mform->elementExists($property)) {
if (empty($CFG->grade_hideforcedsettings)) {
$mform->hardFreeze($property);
} else {
if ($mform->elementExists($property)) {
$mform->removeElement($property);
}
}
}
}
}
if ($CFG->grade_droplow > 0) {
if ($mform->elementExists('keephigh')) {
$mform->removeElement('keephigh');
}
} else if ($CFG->grade_keephigh > 0) {
if ($mform->elementExists('droplow')) {
$mform->removeElement('droplow');
}
}
if ($id = $mform->getElementValue('id')) {
$grade_category = grade_category::fetch(array('id'=>$id));
$grade_item = $grade_category->load_grade_item();
// remove agg coef if not used
if ($grade_category->is_course_category()) {
if ($mform->elementExists('parentcategory')) {
$mform->removeElement('parentcategory');
}
if ($mform->elementExists('currentparentaggregation')) {
$mform->removeElement('currentparentaggregation');
}
} else {
// if we wanted to change parent of existing category - we would have to verify there are no circular references in parents!!!
if ($mform->elementExists('parentcategory')) {
$mform->hardFreeze('parentcategory');
}
$parent_cat = $grade_category->get_parent_category();
$mform->setDefault('currentparentaggregation', $this->aggregation_options[$parent_cat->aggregation]);
}
// Prevent the user from using drop lowest/keep highest when the aggregation method cannot handle it.
if (!$grade_category->can_apply_limit_rules()) {
if ($mform->elementExists('keephigh')) {
$mform->setConstant('keephigh', 0);
$mform->hardFreeze('keephigh');
}
if ($mform->elementExists('droplow')) {
$mform->setConstant('droplow', 0);
$mform->hardFreeze('droplow');
}
}
if ($grade_item->is_calculated()) {
// following elements are ignored when calculation formula used
if ($mform->elementExists('aggregation')) {
$mform->removeElement('aggregation');
}
if ($mform->elementExists('keephigh')) {
$mform->removeElement('keephigh');
}
if ($mform->elementExists('droplow')) {
$mform->removeElement('droplow');
}
if ($mform->elementExists('aggregateonlygraded')) {
$mform->removeElement('aggregateonlygraded');
}
if ($mform->elementExists('aggregateoutcomes')) {
$mform->removeElement('aggregateoutcomes');
}
}
// If it is a course category, remove the "required" rule from the "fullname" element
if ($grade_category->is_course_category()) {
unset($mform->_rules['fullname']);
$key = array_search('fullname', $mform->_required);
unset($mform->_required[$key]);
}
// If it is a course category and its fullname is ?, show an empty field
if ($grade_category->is_course_category() && $mform->getElementValue('fullname') == '?') {
$mform->setDefault('fullname', '');
}
// remove unwanted aggregation options
if ($mform->elementExists('aggregation')) {
$allaggoptions = array_keys($this->aggregation_options);
$agg_el =& $mform->getElement('aggregation');
$visible = explode(',', $CFG->grade_aggregations_visible);
if (!is_null($grade_category->aggregation)) {
// current type is always visible
$visible[] = $grade_category->aggregation;
}
foreach ($allaggoptions as $type) {
if (!in_array($type, $visible)) {
$agg_el->removeOption($type);
}
}
}
} else {
// adding new category
if ($mform->elementExists('currentparentaggregation')) {
$mform->removeElement('currentparentaggregation');
}
// remove unwanted aggregation options
if ($mform->elementExists('aggregation')) {
$allaggoptions = array_keys($this->aggregation_options);
$agg_el =& $mform->getElement('aggregation');
$visible = explode(',', $CFG->grade_aggregations_visible);
foreach ($allaggoptions as $type) {
if (!in_array($type, $visible)) {
$agg_el->removeOption($type);
}
}
}
$mform->removeElement('grade_item_rescalegrades');
}
// no parent header for course category
if (!$mform->elementExists('parentcategory')) {
$mform->removeElement('headerparent');
}
/// GRADE ITEM
if ($id = $mform->getElementValue('id')) {
$grade_category = grade_category::fetch(array('id'=>$id));
$grade_item = $grade_category->load_grade_item();
// Load appropriate "hidden"/"hidden until" defaults.
if ($grade_item->is_hiddenuntil()) {
$mform->setDefault('grade_item_hiddenuntil', $grade_item->get_hidden());
} else {
$mform->setDefault('grade_item_hidden', $grade_item->get_hidden());
}
if ($grade_item->is_outcome_item()) {
// we have to prevent incompatible modifications of outcomes if outcomes disabled
$mform->removeElement('grade_item_grademax');
if ($mform->elementExists('grade_item_grademin')) {
$mform->removeElement('grade_item_grademin');
}
$mform->removeElement('grade_item_gradetype');
$mform->removeElement('grade_item_display');
$mform->removeElement('grade_item_decimals');
$mform->hardFreeze('grade_item_scaleid');
// Only show the option to rescale grades on a category if its corresponding grade_item has overridden grade_grades.
} else if ($grade_item->has_overridden_grades()) {
// Can't change the grade type or the scale if there are grades.
$mform->hardFreeze('grade_item_gradetype, grade_item_scaleid');
// If we are using scles then remove the unnecessary rescale and grade fields.
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
$mform->removeElement('grade_item_rescalegrades');
$mform->removeElement('grade_item_grademax');
if ($mform->elementExists('grade_item_grademin')) {
$mform->removeElement('grade_item_grademin');
}
} else { // Not using scale, so remove it.
$mform->removeElement('grade_item_scaleid');
$mform->disabledIf('grade_item_grademax', 'grade_item_rescalegrades', 'eq', '');
$mform->disabledIf('grade_item_grademin', 'grade_item_rescalegrades', 'eq', '');
}
} else { // Remove the rescale element if there are no grades.
$mform->removeElement('grade_item_rescalegrades');
}
//remove the aggregation coef element if not needed
if ($grade_item->is_course_item()) {
if ($mform->elementExists('grade_item_aggregationcoef')) {
$mform->removeElement('grade_item_aggregationcoef');
}
if ($mform->elementExists('grade_item_weightoverride')) {
$mform->removeElement('grade_item_weightoverride');
}
if ($mform->elementExists('grade_item_aggregationcoef2')) {
$mform->removeElement('grade_item_aggregationcoef2');
}
} else {
if ($grade_item->is_category_item()) {
$category = $grade_item->get_item_category();
$parent_category = $category->get_parent_category();
} else {
$parent_category = $grade_item->get_parent_category();
}
$parent_category->apply_forced_settings();
if (!$parent_category->is_aggregationcoef_used()) {
if ($mform->elementExists('grade_item_aggregationcoef')) {
$mform->removeElement('grade_item_aggregationcoef');
}
} else {
$coefstring = $grade_item->get_coefstring();
if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') {
// advcheckbox is not compatible with disabledIf!
$coefstring = 'aggregationcoefextrasum';
$element =& $mform->createElement('checkbox', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
} else {
$element =& $mform->createElement('text', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
}
$mform->insertElementBefore($element, 'parentcategory');
$mform->addHelpButton('grade_item_aggregationcoef', $coefstring, 'grades');
}
// Remove fields used by natural weighting if the parent category is not using natural weighting.
// Or if the item is a scale and scales are not used in aggregation.
if ($parent_category->aggregation != GRADE_AGGREGATE_SUM
|| (empty($CFG->grade_includescalesinaggregation) && $grade_item->gradetype == GRADE_TYPE_SCALE)) {
if ($mform->elementExists('grade_item_weightoverride')) {
$mform->removeElement('grade_item_weightoverride');
}
if ($mform->elementExists('grade_item_aggregationcoef2')) {
$mform->removeElement('grade_item_aggregationcoef2');
}
}
}
}
}
function validation($data, $files) {
global $COURSE;
$gradeitem = false;
if ($data['id']) {
$gradecategory = grade_category::fetch(array('id' => $data['id']));
$gradeitem = $gradecategory->load_grade_item();
}
$errors = parent::validation($data, $files);
if (array_key_exists('grade_item_gradetype', $data) and $data['grade_item_gradetype'] == GRADE_TYPE_SCALE) {
if (empty($data['grade_item_scaleid'])) {
$errors['grade_item_scaleid'] = get_string('missingscale', 'grades');
}
}
// We need to make all the validations related with grademax and grademin
// with them being correct floats, keeping the originals unmodified for
// later validations / showing the form back...
// TODO: Note that once MDL-73994 is fixed we'll have to re-visit this and
// adapt the code below to the new values arriving here, without forgetting
// the special case of empties and nulls.
$grademax = isset($data['grade_item_grademax']) ? unformat_float($data['grade_item_grademax']) : null;
$grademin = isset($data['grade_item_grademin']) ? unformat_float($data['grade_item_grademin']) : null;
if (!is_null($grademin) and !is_null($grademax)) {
if (($grademax != 0 OR $grademin != 0) AND
($grademax == $grademin OR $grademax < $grademin)) {
$errors['grade_item_grademin'] = get_string('incorrectminmax', 'grades');
$errors['grade_item_grademax'] = get_string('incorrectminmax', 'grades');
}
}
if ($data['id'] && $gradeitem->has_overridden_grades()) {
if ($gradeitem->gradetype == GRADE_TYPE_VALUE) {
if (grade_floats_different($grademin, $gradeitem->grademin) ||
grade_floats_different($grademax, $gradeitem->grademax)) {
if (empty($data['grade_item_rescalegrades'])) {
$errors['grade_item_rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades');
}
}
}
}
return $errors;
}
}
+292
View File
@@ -0,0 +1,292 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Edit a user's grade for a particular activity
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'grade_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$itemid = optional_param('itemid', 0, PARAM_INT);
$userid = optional_param('userid', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/grade.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
if ($itemid !== 0) {
$url->param('itemid', $itemid);
}
if ($userid !== 0) {
$url->param('userid', $userid);
}
$PAGE->set_url($url);
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
$PAGE->set_pagelayout('incourse');
require_login($course);
$context = context_course::instance($course->id);
if (!has_capability('moodle/grade:manage', $context)) {
require_capability('moodle/grade:edit', $context);
}
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report/index.php?id='.$course->id);
// security checks!
if (!empty($id)) {
if (!$grade = $DB->get_record('grade_grades', array('id' => $id))) {
throw new \moodle_exception('invalidgroupid');
}
if (!empty($itemid) and $itemid != $grade->itemid) {
throw new \moodle_exception('invaliditemid');
}
$itemid = $grade->itemid;
if (!empty($userid) and $userid != $grade->userid) {
throw new \moodle_exception('invaliduser');
}
$userid = $grade->userid;
unset($grade);
} else if (empty($userid) or empty($itemid)) {
throw new \moodle_exception('missinguseranditemid');
}
if (!$grade_item = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$courseid))) {
throw new \moodle_exception('cannotfindgradeitem');
}
// now verify grading user has access to all groups or is member of the same group when separate groups used in course
if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
if ($groups = groups_get_all_groups($COURSE->id, $userid)) {
$ok = false;
foreach ($groups as $group) {
if (groups_is_member($group->id, $USER->id)) {
$ok = true;
}
}
if (!$ok) {
throw new \moodle_exception('cannotgradeuser');
}
} else {
throw new \moodle_exception('cannotgradeuser');
}
}
$mform = new edit_grade_form(null, array('grade_item'=>$grade_item, 'gpr'=>$gpr));
if ($grade = $DB->get_record('grade_grades', array('itemid' => $grade_item->id, 'userid' => $userid))) {
// always clean existing feedback - grading should not have XSS risk
if (empty($grade->feedback)) {
$grade->feedback = '';
} else {
$options = new stdClass();
$options->filter = false;
$options->noclean = false;
$options->para = false;
$grade->feedback = format_text($grade->feedback, $grade->feedbackformat, $options);
}
$grade->feedbackformat = FORMAT_HTML;
$grade->locked = $grade->locked > 0 ? 1:0;
$grade->overridden = $grade->overridden > 0 ? 1:0;
$grade->excluded = $grade->excluded > 0 ? 1:0;
if ($grade->hidden > 1) {
$grade->hiddenuntil = $grade->hidden;
$grade->hidden = 1;
} else {
$grade->hiddenuntil = 0;
}
if ($grade_item->is_hidden()) {
$grade->hidden = 1;
}
if ($grade_item->is_locked()) {
$grade->locked = 1;
}
// normalize the final grade value
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
if (empty($grade->finalgrade)) {
$grade->finalgrade = -1;
} else {
$grade->finalgrade = (int)$grade->finalgrade;
}
} else if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
$grade->finalgrade = format_float($grade->finalgrade, $grade_item->get_decimals());
}
$grade->oldgrade = $grade->finalgrade;
$grade->oldfeedback = $grade->feedback;
$grade->feedback = array('text'=>$grade->feedback, 'format'=>$grade->feedbackformat);
$mform->set_data($grade);
} else {
$grade = new stdClass();
$grade->feedback = array('text'=>'', 'format'=>FORMAT_HTML);
$mform->set_data(array('itemid'=>$itemid, 'userid'=>$userid, 'locked'=>$grade_item->locked, 'locktime'=>$grade_item->locktime));
}
if ($mform->is_cancelled()) {
redirect($returnurl);
// form processing
} else if ($data = $mform->get_data(false)) {
if (isset($data->feedback) && is_array($data->feedback)) {
$data->feedbackformat = $data->feedback['format'];
$data->feedback = $data->feedback['text'] ?? null;
}
$old_grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true); //might not exist yet
// fix no grade for scales
if (!isset($data->finalgrade) or $data->finalgrade == $data->oldgrade) {
$data->finalgrade = $old_grade_grade->finalgrade;
} else if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
if ($data->finalgrade < 1) {
$data->finalgrade = NULL;
}
} else if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
$data->finalgrade = unformat_float($data->finalgrade);
} else {
//this should not happen
$data->finalgrade = $old_grade_grade->finalgrade;
}
// the overriding of feedback is tricky - we have to care about external items only
if (!property_exists($data, 'feedback') or $data->feedback == $data->oldfeedback) {
$data->feedback = $old_grade_grade->feedback;
$data->feedbackformat = $old_grade_grade->feedbackformat;
}
// update final grade or feedback
// when we set override grade the first time, it happens here
$grade_item->update_final_grade($data->userid, $data->finalgrade, 'editgrade', $data->feedback, $data->feedbackformat);
$grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true);
$grade_grade->grade_item =& $grade_item; // no db fetching
if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:edit', $context)) {
// change overridden flag
if (!isset($data->overridden)) {
$data->overridden = 0; // checkbox unticked
}
$grade_grade->set_overridden($data->overridden);
}
if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:hide', $context)) {
$hidden = empty($data->hidden) ? 0: $data->hidden;
$hiddenuntil = empty($data->hiddenuntil) ? 0: $data->hiddenuntil;
if ($grade_item->is_hidden()) {
if ($old_grade_grade->hidden == 1 and $hiddenuntil == 0) {
//nothing to do - grade was originally hidden, we want to keep it that way
} else {
$grade_grade->set_hidden($hiddenuntil);
}
} else {
if ($hiddenuntil) {
$grade_grade->set_hidden($hiddenuntil);
} else {
$grade_grade->set_hidden($hidden); // checkbox data might be undefined
}
}
}
if (isset($data->locked) and !$grade_item->is_locked()) {
if (($old_grade_grade->locked or $old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
//ignore data
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
//ignore data
} else {
$grade_grade->set_locktime($data->locktime); //set_lock may reset locktime
$grade_grade->set_locked($data->locked, false, true);
// reload grade in case it was regraded from activity
$grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true);
$grade_grade->grade_item =& $grade_item; // no db fetching
}
}
if (isset($data->excluded) and has_capability('moodle/grade:manage', $context)) {
$grade_grade->set_excluded($data->excluded);
}
// detect cases when we need to do full regrading
if ($old_grade_grade->excluded != $grade_grade->excluded) {
$parent = $grade_item->get_parent_category();
$parent->force_regrading();
} else if ($old_grade_grade->overridden != $grade_grade->overridden and empty($grade_grade->overridden)) { // only when unoverridding
$grade_item->force_regrading();
} else if ($old_grade_grade->locktime != $grade_grade->locktime) {
$grade_item->force_regrading();
}
redirect($returnurl);
}
$strgrades = get_string('grades');
$strgraderreport = get_string('graderreport', 'grades');
$strgradeedit = get_string('editgrade', 'grades');
$struser = get_string('user');
grade_build_nav(__FILE__, $strgradeedit, array('courseid' => $courseid));
/*********** BEGIN OUTPUT *************/
$PAGE->set_title($strgrades . ': ' . $strgraderreport . ': ' . $strgradeedit);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($strgradeedit);
echo $OUTPUT->box_start();
// Form if in edit or add modes
$mform->display();
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
die;
+216
View File
@@ -0,0 +1,216 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A moodleform to allow the editing of a user's grade for a particular activity
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_grade_form extends moodleform {
function definition() {
global $CFG, $COURSE, $DB;
$mform =& $this->_form;
$grade_item = $this->_customdata['grade_item'];
$gpr = $this->_customdata['gpr'];
if ($grade_item->is_course_item()) {
$grade_category = null;
} else if ($grade_item->is_category_item()) {
$grade_category = $grade_item->get_item_category();
$grade_category = $grade_category->get_parent_category();
} else {
$grade_category = $grade_item->get_parent_category();
}
/// information fields
$mform->addElement('static', 'user', get_string('user'));
$mform->addElement('static', 'itemname', get_string('itemname', 'grades'));
$mform->addElement('checkbox', 'overridden', get_string('overridden', 'grades'));
$mform->addHelpButton('overridden', 'overridden', 'grades');
/// actual grade - numeric or scale
if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
// numeric grade
$mform->addElement('text', 'finalgrade', get_string('finalgrade', 'grades'));
$mform->setType('finalgrade', PARAM_RAW);
$mform->addHelpButton('finalgrade', 'finalgrade', 'grades');
$mform->disabledIf('finalgrade', 'overridden', 'notchecked');
} else if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
// scale grade
$scaleopt = array();
if (empty($grade_item->outcomeid)) {
$scaleopt[-1] = get_string('nograde');
} else {
$scaleopt[-1] = get_string('nooutcome', 'grades');
}
$i = 1;
if ($scale = $DB->get_record('scale', array('id' => $grade_item->scaleid))) {
foreach (explode(",", $scale->scale) as $option) {
$scaleopt[$i] = $option;
$i++;
}
}
$mform->addElement('select', 'finalgrade', get_string('finalgrade', 'grades'), $scaleopt);
$mform->addHelpButton('finalgrade', 'finalgrade', 'grades');
$mform->disabledIf('finalgrade', 'overridden', 'notchecked');
}
$mform->addElement('advcheckbox', 'excluded', get_string('excluded', 'grades'));
$mform->addHelpButton('excluded', 'excluded', 'grades');
/// hiding
/// advcheckbox is not compatible with disabledIf !!
$mform->addElement('checkbox', 'hidden', get_string('hidden', 'grades'));
$mform->addHelpButton('hidden', 'hidden', 'grades');
$mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked');
/// locking
$mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addHelpButton('locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
// Feedback format is automatically converted to html if user has enabled editor
$feedbackoptions = array('maxfiles'=>0, 'maxbytes'=>0); //TODO: no files here for now, if ever gets implemented use component 'grade' and filearea 'feedback'
$mform->addElement('editor', 'feedback', get_string('feedback', 'grades'), null, $feedbackoptions);
$mform->addHelpButton('feedback', 'feedback', 'grades');
$mform->setType('text', PARAM_RAW); // to be cleaned before display, no XSS risk
$mform->disabledIf('feedback', 'overridden');
// hidden params
$mform->addElement('hidden', 'oldgrade');
$mform->setType('oldgrade', PARAM_RAW);
$mform->addElement('hidden', 'oldfeedback');
$mform->setType('oldfeedback', PARAM_RAW);
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'itemid', 0);
$mform->setType('itemid', PARAM_INT);
$mform->addElement('hidden', 'userid', 0);
$mform->setType('userid', PARAM_INT);
$mform->addElement('hidden', 'courseid', $COURSE->id);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
}
function definition_after_data() {
global $CFG, $COURSE, $DB;
$context = context_course::instance($COURSE->id);
$mform =& $this->_form;
$grade_item = $this->_customdata['grade_item'];
// fill in user name if user still exists
$userid = $mform->getElementValue('userid');
if ($user = $DB->get_record('user', array('id' => $userid))) {
$username = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'">'.fullname($user).'</a>';
$user_el =& $mform->getElement('user');
$user_el->setValue($username);
}
// add activity name + link
if ($grade_item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid);
$itemname = '<a href="'.$CFG->wwwroot.'/mod/'.$grade_item->itemmodule.'/view.php?id='.$cm->id.'">'.$grade_item->get_name().'</a>';
} else {
$itemname = $grade_item->get_name();
}
$itemname_el =& $mform->getElement('itemname');
$itemname_el->setValue($itemname);
// access control - disable not allowed elements
if (!has_capability('moodle/grade:manage', $context)) {
$mform->hardFreeze('excluded');
}
if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
$mform->hardFreeze('hidden');
$mform->hardFreeze('hiddenuntil');
}
$old_grade_grade = new grade_grade(array('itemid'=>$grade_item->id, 'userid'=>$userid));
$gradeitemoverridable = $grade_item->is_overridable_item();
if (!$gradeitemoverridable) {
$mform->removeElement('overridden');
}
if ($grade_item->is_hidden()) {
$mform->hardFreeze('hidden');
}
if ($old_grade_grade->is_locked()) {
if ($grade_item->is_locked()) {
$mform->hardFreeze('locked');
$mform->hardFreeze('locktime');
}
if ($gradeitemoverridable) {
$mform->hardFreeze('overridden');
}
$mform->hardFreeze('finalgrade');
$mform->hardFreeze('feedback');
} else {
if (empty($old_grade_grade->id)) {
$old_grade_grade->locked = $grade_item->locked;
$old_grade_grade->locktime = $grade_item->locktime;
}
if (($old_grade_grade->locked or $old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
$mform->hardFreeze('locked');
$mform->hardFreeze('locktime');
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
$mform->hardFreeze('locked');
$mform->hardFreeze('locktime');
}
}
}
}
+286
View File
@@ -0,0 +1,286 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* The Gradebook setup page.
*
* @package core_grades
* @copyright 2008 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('NO_OUTPUT_BUFFERING', true); // The progress bar may be used here.
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences
require_once $CFG->dirroot.'/grade/edit/tree/lib.php';
$courseid = required_param('id', PARAM_INT);
$action = optional_param('action', 0, PARAM_ALPHA);
$eid = optional_param('eid', 0, PARAM_ALPHANUM);
$weightsadjusted = optional_param('weightsadjusted', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid));
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
/// Make sure they can even access this course
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
$PAGE->requires->js_call_amd('core_grades/edittree_index', 'init', [$courseid, $USER->id]);
$PAGE->requires->js_call_amd('core_grades/gradebooksetup_forms', 'init');
$decsep = get_string('decsep', 'langconfig');
// This setting indicates if we should use algorithm prior to MDL-49257 fix for calculating extra credit weights.
$gradebookcalculationfreeze = (int) get_config('core', 'gradebook_calculations_freeze_' . $courseid);
$oldextracreditcalculation = $gradebookcalculationfreeze && ($gradebookcalculationfreeze <= 20150619);
$PAGE->requires->js_call_amd('core_grades/edittree_weights', 'init', [$decsep, $oldextracreditcalculation]);
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
$returnurl = $gpr->get_return_url(null);
// get the grading tree object
// note: total must be first for moving to work correctly, if you want it last moving code must be rewritten!
$gtree = new grade_tree($courseid, false, false);
if (empty($eid)) {
$element = null;
$object = null;
} else {
if (!$element = $gtree->locate_element($eid)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$object = $element['object'];
}
$switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggregationposition);
$strgrades = get_string('grades');
$strgraderreport = get_string('graderreport', 'grades');
$moving = false;
$movingeid = false;
if ($action == 'moveselect') {
if ($eid and confirm_sesskey()) {
$movingeid = $eid;
$moving=true;
}
}
$gradeedittree = new grade_edit_tree($gtree, $movingeid, $gpr);
switch ($action) {
case 'duplicate':
if ($eid and confirm_sesskey()) {
if (!$el = $gtree->locate_element($eid)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$object->duplicate();
redirect($returnurl);
}
break;
case 'delete':
if ($eid && confirm_sesskey()) {
if (!$gradeedittree->element_deletable($element)) {
// no deleting of external activities - they would be recreated anyway!
// exception is activity without grading or misconfigured activities
break;
}
$confirm = optional_param('confirm', 0, PARAM_BOOL);
if ($confirm) {
$object->delete('grade/report/grader/category');
redirect($returnurl);
}
}
break;
case 'autosort':
//TODO: implement autosorting based on order of mods on course page, categories first, manual items last
break;
case 'move':
if ($eid and confirm_sesskey()) {
$moveafter = required_param('moveafter', PARAM_ALPHANUM);
$first = optional_param('first', false, PARAM_BOOL); // If First is set to 1, it means the target is the first child of the category $moveafter
if(!$after_el = $gtree->locate_element($moveafter)) {
throw new \moodle_exception('invalidelementid', '', $returnurl);
}
$after = $after_el['object'];
$sortorder = $after->get_sortorder();
if (!$first) {
$parent = $after->get_parent_category();
$object->set_parent($parent->id);
} else {
$object->set_parent($after->id);
}
$object->move_after_sortorder($sortorder);
redirect($returnurl);
}
break;
default:
break;
}
// If we go straight to the db to update an element we need to recreate the tree as
// $gradeedittree has already been constructed.
// Ideally we could do the updates through $gradeedittree to avoid recreating it.
$recreatetree = false;
if ($data = data_submitted() and confirm_sesskey()) {
// Perform bulk actions first
if (!empty($data->bulkmove)) {
$elements = array();
foreach ($data as $key => $value) {
if (preg_match('/select_(ig[0-9]*)/', $key, $matches)) {
$elements[] = $matches[1];
}
}
$gradeedittree->move_elements($elements, $returnurl);
}
// Update weights (extra credits) on categories and items.
foreach ($data as $key => $value) {
if (preg_match('/^weight_([0-9]+)$/', $key, $matches)) {
$aid = $matches[1];
$value = unformat_float($value);
$value = clean_param($value, PARAM_FLOAT);
$grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
// Convert weight to aggregation coef2.
$aggcoef = $grade_item->get_coefstring();
if ($aggcoef == 'aggregationcoefextraweightsum') {
// The field 'weight' should only be sent when the checkbox 'weighoverride' is checked,
// so there is not need to set weightoverride here, it is done below.
$value = $value / 100.0;
$grade_item->aggregationcoef2 = $value;
} else if ($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoefextraweight') {
$grade_item->aggregationcoef = $value;
}
$grade_item->update();
$recreatetree = true;
// Grade item checkbox inputs.
} elseif (preg_match('/^(weightoverride)_([0-9]+)$/', $key, $matches)) {
$param = $matches[1];
$aid = $matches[2];
$value = clean_param($value, PARAM_BOOL);
$grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
$grade_item->$param = $value;
$grade_item->update();
$recreatetree = true;
}
}
}
$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
/**
* Callback function to adjust the URL if weights changed after the
* regrade.
*
* @param int $courseid The course ID
* @param array $originalweights The weights before the regrade
* @param int $weightsadjusted Whether weights have been adjusted
* @return moodle_url A URL to redirect to after regrading when a progress bar is displayed.
*/
$grade_edit_tree_index_checkweights = function() use ($courseid, $originalweights, &$weightsadjusted) {
global $PAGE;
$alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
if (array_diff($originalweights, $alteredweights)) {
$weightsadjusted = 1;
return new moodle_url($PAGE->url, array('weightsadjusted' => $weightsadjusted));
}
return $PAGE->url;
};
if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_checkweights)) {
$recreatetree = true;
}
$actionbar = new \core_grades\output\gradebook_setup_action_bar($context);
print_grade_page_head($courseid, 'settings', 'setup', false,
false, false, true, null, null, null, $actionbar);
// Print Table of categories and items
echo $OUTPUT->box_start('gradetreebox generalbox');
// Did we update something in the db and thus invalidate $gradeedittree?
if ($recreatetree) {
$gradeedittree = new grade_edit_tree($gtree, $movingeid, $gpr);
}
$tpldata = (object) [
'actionurl' => $returnurl,
'sesskey' => sesskey(),
'movingmodeenabled' => $moving,
'courseid' => $courseid
];
// Check to see if we have a normalisation message to send.
if ($weightsadjusted) {
$notification = new \core\output\notification(get_string('weightsadjusted', 'grades'), \core\output\notification::NOTIFY_INFO);
$tpldata->notification = $notification->export_for_template($OUTPUT);
}
$tpldata->table = html_writer::table($gradeedittree->table);
// If not in moving mode and there is more than one grade category, then initialise the bulk action module.
if (!$moving && count($gradeedittree->categories) > 1) {
$PAGE->requires->js_call_amd('core_grades/bulkactions/edit/tree/bulk_actions', 'init', [$courseid]);
}
$footercontent = $OUTPUT->render_from_template('core_grades/edit_tree_sticky_footer', $tpldata);
$stickyfooter = new core\output\sticky_footer($footercontent);
$tpldata->stickyfooter = $OUTPUT->render($stickyfooter);
echo $OUTPUT->render_from_template('core_grades/edit_tree', $tpldata);
echo $OUTPUT->box_end();
$PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['gradetreeform']);
echo $OUTPUT->footer();
die;
+215
View File
@@ -0,0 +1,215 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Edit the grade options for an individual grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_grades\form\add_item;
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'item_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/item.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$courseid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$course->id);
$heading = get_string('itemsedit', 'grades');
if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
// redirect if outcomeid present
if (!empty($grade_item->outcomeid) && !empty($CFG->enableoutcomes)) {
$url = new moodle_url('/grade/edit/tree/outcomeitem.php', ['id' => $id, 'courseid' => $courseid]);
redirect($gpr->add_url_params($url));
}
if ($grade_item->is_course_item() or $grade_item->is_category_item()) {
$grade_category = $grade_item->get_item_category();
$url = new moodle_url('/grade/edit/tree/category.php', ['id' => $grade_category->id, 'courseid' => $courseid]);
redirect($gpr->add_url_params($url));
}
$item = $grade_item->get_record_data();
$parent_category = $grade_item->get_parent_category();
$item->parentcategory = $parent_category->id;
} else {
$heading = get_string('newitem', 'grades');
$grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
$item = $grade_item->get_record_data();
$parent_category = grade_category::fetch_course_category($courseid);
$item->parentcategory = $parent_category->id;
}
$decimalpoints = $grade_item->get_decimals();
if ($item->hidden > 1) {
$item->hiddenuntil = $item->hidden;
$item->hidden = 0;
} else {
$item->hiddenuntil = 0;
}
$item->locked = !empty($item->locked);
$item->grademax = format_float($item->grademax, $decimalpoints);
$item->grademin = format_float($item->grademin, $decimalpoints);
$item->gradepass = format_float($item->gradepass, $decimalpoints);
$item->multfactor = format_float($item->multfactor, 4);
$item->plusfactor = format_float($item->plusfactor, 4);
if ($parent_category->aggregation == GRADE_AGGREGATE_SUM or $parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$item->aggregationcoef = $item->aggregationcoef == 0 ? 0 : 1;
} else {
$item->aggregationcoef = format_float($item->aggregationcoef, 4);
}
if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$item->aggregationcoef2 = format_float($item->aggregationcoef2 * 100.0);
}
$item->cancontrolvisibility = $grade_item->can_control_visibility();
$mform = new edit_item_form(null, array('current'=>$item, 'gpr'=>$gpr));
$simpleform = new add_item(null, ['itemid' => $grade_item->id, 'courseid' => $courseid, 'gpr' => $gpr]);
// Data has been carried over from the dynamic form.
if ($simpledata = $simpleform->get_submitted_data()) {
$mform->set_data($simpledata);
}
if ($mform->is_cancelled()) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
// This is a new item, and the category chosen is different than the default category.
if (empty($grade_item->id) && isset($data->parentcategory) && $parent_category->id != $data->parentcategory) {
$parent_category = grade_category::fetch(array('id' => $data->parentcategory));
}
// If unset, give the aggregation values a default based on parent aggregation method.
$defaults = grade_category::get_default_aggregation_coefficient_values($parent_category->aggregation);
if (!isset($data->aggregationcoef) || $data->aggregationcoef == '') {
$data->aggregationcoef = $defaults['aggregationcoef'];
}
if (!isset($data->weightoverride)) {
$data->weightoverride = $defaults['weightoverride'];
}
if (!isset($data->gradepass) || $data->gradepass == '') {
$data->gradepass = 0;
}
if (!isset($data->grademin) || $data->grademin == '') {
$data->grademin = 0;
}
$hide = empty($data->hiddenuntil) ? 0 : $data->hiddenuntil;
if (!$hide) {
$hide = empty($data->hidden) ? 0 : $data->hidden;
}
unset($data->hidden);
unset($data->hiddenuntil);
$locked = empty($data->locked) ? 0: $data->locked;
$locktime = empty($data->locktime) ? 0: $data->locktime;
unset($data->locked);
unset($data->locktime);
$convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef', 'aggregationcoef2');
foreach ($convert as $param) {
if (property_exists($data, $param)) {
$data->$param = unformat_float($data->$param);
}
}
if (isset($data->aggregationcoef2) && $parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$data->aggregationcoef2 = $data->aggregationcoef2 / 100.0;
} else {
$data->aggregationcoef2 = $defaults['aggregationcoef2'];
}
$gradeitem = new grade_item(array('id' => $id, 'courseid' => $courseid));
$oldmin = $gradeitem->grademin;
$oldmax = $gradeitem->grademax;
grade_item::set_properties($gradeitem, $data);
$gradeitem->outcomeid = null;
// Handle null decimals value
if (!property_exists($data, 'decimals') or $data->decimals < 0) {
$gradeitem->decimals = null;
}
if (empty($gradeitem->id)) {
$gradeitem->itemtype = 'manual'; // All new items to be manual only.
$gradeitem->insert();
// set parent if needed
if (isset($data->parentcategory)) {
$gradeitem->set_parent($data->parentcategory, false);
}
} else {
$gradeitem->update();
if (!empty($data->rescalegrades) && $data->rescalegrades == 'yes') {
$newmin = $gradeitem->grademin;
$newmax = $gradeitem->grademax;
$gradeitem->rescale_grades_keep_percentage($oldmin, $oldmax, $newmin, $newmax, 'gradebook');
}
}
if ($item->cancontrolvisibility) {
// Update hiding flag.
$gradeitem->set_hidden($hide, true);
}
$gradeitem->set_locktime($locktime); // Locktime first - it might be removed when unlocking.
$gradeitem->set_locked($locked, false, true);
redirect($returnurl);
}
$PAGE->navbar->add($heading);
print_grade_page_head($courseid, 'settings', null, $heading, false, false, false);
$mform->display();
echo $OUTPUT->footer();
+473
View File
@@ -0,0 +1,473 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A moodleform allowing the editing of the grade options for an individual grade item
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_item_form extends moodleform {
private $displayoptions;
function definition() {
global $COURSE, $CFG, $DB;
$mform =& $this->_form;
$item = $this->_customdata['current'];
/// visible elements
$mform->addElement('header', 'general', get_string('gradeitem', 'grades'));
$mform->addElement('text', 'itemname', get_string('itemname', 'grades'));
$mform->setType('itemname', PARAM_TEXT);
$mform->addElement('text', 'iteminfo', get_string('iteminfo', 'grades'));
$mform->addHelpButton('iteminfo', 'iteminfo', 'grades');
$mform->setType('iteminfo', PARAM_TEXT);
$mform->addElement('text', 'idnumber', get_string('idnumbermod'));
$mform->addHelpButton('idnumber', 'idnumbermod');
$mform->setType('idnumber', PARAM_RAW);
if (!empty($item->id)) {
$gradeitem = new grade_item(array('id' => $item->id, 'courseid' => $item->courseid));
// If grades exist set a message so the user knows why they can not alter the grade type or scale.
// We could never change the grade type for external items, so only need to show this for manual grade items.
if ($gradeitem->has_grades() && !$gradeitem->is_external_item()) {
// Set a message so the user knows why they can not alter the grade type or scale.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$gradesexistmsg = get_string('modgradecantchangegradetyporscalemsg', 'grades');
} else {
$gradesexistmsg = get_string('modgradecantchangegradetypemsg', 'grades');
}
$gradesexisthtml = '<div class=\'alert\'>' . $gradesexistmsg . '</div>';
$mform->addElement('static', 'gradesexistmsg', '', $gradesexisthtml);
}
}
// Manual grade items cannot have grade type GRADE_TYPE_NONE.
$options = array(GRADE_TYPE_VALUE => get_string('typevalue', 'grades'),
GRADE_TYPE_SCALE => get_string('typescale', 'grades'),
GRADE_TYPE_TEXT => get_string('typetext', 'grades'));
$mform->addElement('select', 'gradetype', get_string('gradetype', 'grades'), $options);
$mform->addHelpButton('gradetype', 'gradetype', 'grades');
$mform->setDefault('gradetype', GRADE_TYPE_VALUE);
//$mform->addElement('text', 'calculation', get_string('calculation', 'grades'));
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT);
//$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE);
$options = array(0=>get_string('usenoscale', 'grades'));
if ($scales = grade_scale::fetch_all_local($COURSE->id)) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
if ($scales = grade_scale::fetch_all_global()) {
foreach ($scales as $scale) {
$options[$scale->id] = $scale->get_name();
}
}
// ugly BC hack - it was possible to use custom scale from other courses :-(
if (!empty($item->scaleid) and !isset($options[$item->scaleid])) {
if ($scale = grade_scale::fetch(array('id'=>$item->scaleid))) {
$options[$scale->id] = $scale->get_name().get_string('incorrectcustomscale', 'grades');
}
}
$mform->addElement('select', 'scaleid', get_string('scale'), $options);
$mform->addHelpButton('scaleid', 'typescale', 'grades');
$mform->disabledIf('scaleid', 'gradetype', 'noteq', GRADE_TYPE_SCALE);
$choices = array();
$choices[''] = get_string('choose');
$choices['no'] = get_string('no');
$choices['yes'] = get_string('yes');
$mform->addElement('select', 'rescalegrades', get_string('modgraderescalegrades', 'grades'), $choices);
$mform->addHelpButton('rescalegrades', 'modgraderescalegrades', 'grades');
$mform->disabledIf('rescalegrades', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
$mform->addElement('float', 'grademax', get_string('grademax', 'grades'));
$mform->addHelpButton('grademax', 'grademax', 'grades');
$mform->disabledIf('grademax', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
if ((bool) get_config('moodle', 'grade_report_showmin')) {
$mform->addElement('float', 'grademin', get_string('grademin', 'grades'));
$mform->addHelpButton('grademin', 'grademin', 'grades');
$mform->disabledIf('grademin', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
}
$mform->addElement('float', 'gradepass', get_string('gradepass', 'grades'));
$mform->addHelpButton('gradepass', 'gradepass', 'grades');
$mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->addElement('float', 'multfactor', get_string('multfactor', 'grades'));
$mform->addHelpButton('multfactor', 'multfactor', 'grades');
$mform->disabledIf('multfactor', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('multfactor', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->addElement('float', 'plusfactor', get_string('plusfactor', 'grades'));
$mform->addHelpButton('plusfactor', 'plusfactor', 'grades');
$mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_TEXT);
/// grade display prefs
$default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype);
$options = array(GRADE_DISPLAY_TYPE_DEFAULT => get_string('default', 'grades'),
GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'),
GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'),
GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'),
GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'),
GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades')
);
asort($options);
foreach ($options as $key=>$option) {
if ($key == $default_gradedisplaytype) {
$options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
break;
}
}
$mform->addElement('select', 'display', get_string('gradedisplaytype', 'grades'), $options);
$mform->addHelpButton('display', 'gradedisplaytype', 'grades');
$mform->disabledIf('display', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints);
$options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
$mform->addElement('select', 'decimals', get_string('decimalpoints', 'grades'), $options);
$mform->addHelpButton('decimals', 'decimalpoints', 'grades');
$mform->setDefault('decimals', -1);
$mform->disabledIf('decimals', 'display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
$mform->disabledIf('decimals', 'display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
}
$mform->disabledIf('decimals', 'gradetype', 'eq', GRADE_TYPE_TEXT);
/// hiding
if ($item->cancontrolvisibility) {
$mform->addElement('advcheckbox', 'hidden', get_string('hidden', 'grades'), '', [], [0, 1]);
$mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked');
} else {
$mform->addElement('static', 'hidden', get_string('hidden', 'grades'),
get_string('componentcontrolsvisibility', 'grades'));
// Unset hidden to avoid data override.
unset($item->hidden);
}
$mform->addHelpButton('hidden', 'hidden', 'grades');
/// locking
$mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addHelpButton('locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
/// parent category related settings
$mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
$mform->addElement('advcheckbox', 'weightoverride', get_string('adjustedweight', 'grades'));
$mform->addHelpButton('weightoverride', 'weightoverride', 'grades');
$mform->disabledIf('weightoverride', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('weightoverride', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->addElement('float', 'aggregationcoef2', get_string('weight', 'grades'));
$mform->addHelpButton('aggregationcoef2', 'weight', 'grades');
$mform->disabledIf('aggregationcoef2', 'weightoverride');
$mform->disabledIf('aggregationcoef2', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('aggregationcoef2', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$options = array();
$coefstring = '';
$categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
foreach ($categories as $cat) {
$cat->apply_forced_settings();
$options[$cat->id] = $cat->get_name();
}
if (count($categories) > 1) {
$mform->addElement('select', 'parentcategory', get_string('gradecategory', 'grades'), $options);
}
/// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', $COURSE->id);
$mform->setType('courseid', PARAM_INT);
$mform->addElement('hidden', 'itemtype', 'manual'); // all new items are manual only
$mform->setType('itemtype', PARAM_ALPHA);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
//-------------------------------------------------------------------------------
$this->set_data($item);
}
/// tweak the form - depending on existing data
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
if ($id = $mform->getElementValue('id')) {
$gradeitem = grade_item::fetch(array('id' => $id));
$parentcategory = $gradeitem->get_parent_category();
} else {
// If we do not have an id, we are creating a new grade item.
$gradeitem = new grade_item(array('courseid' => $COURSE->id, 'itemtype' => 'manual'), false);
// Assign the course category to this grade item.
$parentcategory = grade_category::fetch_course_category($COURSE->id);
$gradeitem->parent_category = $parentcategory;
}
if (!$gradeitem->is_raw_used()) {
$mform->removeElement('plusfactor');
$mform->removeElement('multfactor');
}
if ($gradeitem->is_outcome_item()) {
// We have to prevent incompatible modifications of outcomes if outcomes disabled.
$mform->removeElement('grademax');
if ($mform->elementExists('grademin')) {
$mform->removeElement('grademin');
}
$mform->removeElement('gradetype');
$mform->removeElement('display');
$mform->removeElement('decimals');
$mform->hardFreeze('scaleid');
} else {
if ($gradeitem->is_external_item()) {
// Following items are set up from modules and should not be overrided by user.
if ($mform->elementExists('grademin')) {
// The site setting grade_report_showmin may have prevented grademin being added to the form.
$mform->hardFreeze('grademin');
}
$mform->hardFreeze('itemname,gradetype,grademax,scaleid');
if ($gradeitem->itemnumber == 0) {
// The idnumber of grade itemnumber 0 is synced with course_modules.
$mform->hardFreeze('idnumber');
}
// For external items we can not change the grade type, even if no grades exist, so if it is set to
// scale, then remove the grademax and grademin fields from the form - no point displaying them.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$mform->removeElement('grademax');
if ($mform->elementExists('grademin')) {
$mform->removeElement('grademin');
}
} else { // Not using scale, so remove it.
$mform->removeElement('scaleid');
}
// Always remove the rescale grades element if it's an external item.
$mform->removeElement('rescalegrades');
} else if ($gradeitem->has_grades()) {
// Can't change the grade type or the scale if there are grades.
$mform->hardFreeze('gradetype, scaleid');
// If we are using scales then remove the unnecessary rescale and grade fields.
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
$mform->removeElement('rescalegrades');
$mform->removeElement('grademax');
if ($mform->elementExists('grademin')) {
$mform->removeElement('grademin');
}
} else { // Remove the scale field.
$mform->removeElement('scaleid');
// Set the maximum grade to disabled unless a grade is chosen.
$mform->disabledIf('grademax', 'rescalegrades', 'eq', '');
}
} else {
// Remove the rescale element if there are no grades.
$mform->removeElement('rescalegrades');
}
}
// If we wanted to change parent of existing item - we would have to verify there are no circular references in parents!!!
if ($id && $mform->elementExists('parentcategory')) {
$mform->hardFreeze('parentcategory');
}
$parentcategory->apply_forced_settings();
if (!$parentcategory->is_aggregationcoef_used()) {
if ($mform->elementExists('aggregationcoef')) {
$mform->removeElement('aggregationcoef');
}
} else {
$coefstring = $gradeitem->get_coefstring();
if ($coefstring !== '') {
if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') {
// The advcheckbox is not compatible with disabledIf!
$coefstring = 'aggregationcoefextrasum';
$element =& $mform->createElement('checkbox', 'aggregationcoef', get_string($coefstring, 'grades'));
} else {
$element =& $mform->createElement('text', 'aggregationcoef', get_string($coefstring, 'grades'));
}
if ($mform->elementExists('parentcategory')) {
$mform->insertElementBefore($element, 'parentcategory');
} else {
$mform->insertElementBefore($element, 'id');
}
$mform->addHelpButton('aggregationcoef', $coefstring, 'grades');
}
$mform->disabledIf('aggregationcoef', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->disabledIf('aggregationcoef', 'gradetype', 'eq', GRADE_TYPE_TEXT);
$mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $parentcategory->id);
}
// Remove fields used by natural weighting if the parent category is not using natural weighting.
// Or if the item is a scale and scales are not used in aggregation.
if ($parentcategory->aggregation != GRADE_AGGREGATE_SUM
|| (empty($CFG->grade_includescalesinaggregation) && $gradeitem->gradetype == GRADE_TYPE_SCALE)) {
if ($mform->elementExists('weightoverride')) {
$mform->removeElement('weightoverride');
}
if ($mform->elementExists('aggregationcoef2')) {
$mform->removeElement('aggregationcoef2');
}
}
if ($category = $gradeitem->get_item_category()) {
if ($category->aggregation == GRADE_AGGREGATE_SUM) {
if ($mform->elementExists('gradetype')) {
$mform->hardFreeze('gradetype');
}
if ($mform->elementExists('grademin')) {
$mform->hardFreeze('grademin');
}
if ($mform->elementExists('grademax')) {
$mform->hardFreeze('grademax');
}
if ($mform->elementExists('scaleid')) {
$mform->removeElement('scaleid');
}
}
}
// no parent header for course category
if (!$mform->elementExists('aggregationcoef') and !$mform->elementExists('parentcategory')) {
$mform->removeElement('headerparent');
}
}
/// perform extra validation before submission
function validation($data, $files) {
global $COURSE;
$grade_item = false;
if ($data['id']) {
$grade_item = new grade_item(array('id' => $data['id'], 'courseid' => $data['courseid']));
}
$errors = parent::validation($data, $files);
if (array_key_exists('idnumber', $data)) {
if ($grade_item) {
if ($grade_item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid);
} else {
$cm = null;
}
} else {
$grade_item = null;
$cm = null;
}
if (!grade_verify_idnumber($data['idnumber'], $COURSE->id, $grade_item, $cm)) {
$errors['idnumber'] = get_string('idnumbertaken');
}
}
if (array_key_exists('gradetype', $data) and $data['gradetype'] == GRADE_TYPE_SCALE) {
if (empty($data['scaleid'])) {
$errors['scaleid'] = get_string('missingscale', 'grades');
}
}
// We need to make all the validations related with grademax and grademin
// with them being correct floats, keeping the originals unmodified for
// later validations / showing the form back...
// TODO: Note that once MDL-73994 is fixed we'll have to re-visit this and
// adapt the code below to the new values arriving here, without forgetting
// the special case of empties and nulls.
$grademax = isset($data['grademax']) ? unformat_float($data['grademax']) : null;
$grademin = isset($data['grademin']) ? unformat_float($data['grademin']) : null;
if (!is_null($grademin) and !is_null($grademax)) {
if ($grademax == $grademin or $grademax < $grademin) {
$errors['grademin'] = get_string('incorrectminmax', 'grades');
$errors['grademax'] = get_string('incorrectminmax', 'grades');
}
}
// We do not want the user to be able to change the grade type or scale for this item if grades exist.
if ($grade_item && $grade_item->has_grades()) {
// Check that grade type is set - should never not be set unless form has been modified.
if (!isset($data['gradetype'])) {
$errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades');
} else if ($data['gradetype'] !== $grade_item->gradetype) { // Check if we are changing the grade type.
$errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades');
} else if ($data['gradetype'] == GRADE_TYPE_SCALE) {
// Check if we are changing the scale - can't do this when grades exist.
if (isset($data['scaleid']) && ($data['scaleid'] !== $grade_item->scaleid)) {
$errors['scaleid'] = get_string('modgradecantchangescale', 'grades');
}
}
}
if ($grade_item) {
if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
if ((((bool) get_config('moodle', 'grade_report_showmin')) &&
grade_floats_different($grademin, $grade_item->grademin)) ||
grade_floats_different($grademax, $grade_item->grademax)) {
if ($grade_item->has_grades() && empty($data['rescalegrades'])) {
$errors['rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades');
}
}
}
}
return $errors;
}
}
File diff suppressed because it is too large Load Diff
+254
View File
@@ -0,0 +1,254 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A page to create or edit outcome grade items
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_grades\form\add_outcome;
require_once '../../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
require_once 'outcomeitem_form.php';
$courseid = required_param('courseid', PARAM_INT);
$id = optional_param('id', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/outcomeitem.php', array('courseid'=>$courseid));
if ($id !== 0) {
$url->param('id', $id);
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('admin');
navigation_node::override_active_url(new moodle_url('/grade/edit/tree/index.php',
array('id'=>$courseid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/grade:manage', $context);
// default return url
$gpr = new grade_plugin_return();
$returnurl = $gpr->get_return_url('index.php?id='.$course->id);
$mform = new edit_outcomeitem_form(null, array('gpr'=>$gpr));
if ($mform->is_cancelled() || empty($CFG->enableoutcomes)) {
redirect($returnurl);
}
$heading = get_string('outcomeitemsedit', 'grades');
if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
// redirect if outcomeid present
if (empty($grade_item->outcomeid)) {
$url = new moodle_url('/grade/edit/tree/item.php', ['id' => $id, 'courseid' => $courseid]);
redirect($gpr->add_url_params($url));
}
$item = $grade_item->get_record_data();
$parent_category = $grade_item->get_parent_category();
$item->parentcategory = $parent_category->id;
if ($item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($item->itemmodule, $item->iteminstance, $item->courseid);
$item->cmid = $cm->id;
} else {
$item->cmid = 0;
}
} else {
$heading = get_string('newoutcomeitem', 'grades');
$grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
$item = $grade_item->get_record_data();
$item->cmid = 0;
$parent_category = grade_category::fetch_course_category($courseid);
$item->parentcategory = $parent_category->id;
}
$decimalpoints = $grade_item->get_decimals();
if ($item->hidden > 1) {
$item->hiddenuntil = $item->hidden;
$item->hidden = 0;
} else {
$item->hiddenuntil = 0;
}
$item->locked = !empty($item->locked);
$item->gradepass = format_float($item->gradepass, $decimalpoints);
if (empty($parent_category)) {
$item->aggregationcoef = 0;
} else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$item->aggregationcoef = $item->aggregationcoef > 0 ? 1 : 0;
$item->aggregationcoef2 = format_float($item->aggregationcoef2 * 100.0);
} else {
$item->aggregationcoef = format_float($item->aggregationcoef, 4);
}
$mform->set_data($item);
$simpleform = new add_outcome(null, ['itemid' => $grade_item->id, 'courseid' => $courseid, 'gpr' => $gpr]);
// Data has been carried over from the dynamic form.
if ($simpledata = $simpleform->get_submitted_data()) {
$mform->set_data($simpledata);
}
if ($data = $mform->get_data()) {
// This is a new item, and the category chosen is different than the default category.
if (empty($grade_item->id) && isset($data->parentcategory) && $parent_category->id != $data->parentcategory) {
$parent_category = grade_category::fetch(array('id' => $data->parentcategory));
}
// If unset, give the aggregation values a default based on parent aggregation method.
$defaults = grade_category::get_default_aggregation_coefficient_values($parent_category->aggregation);
if (!isset($data->aggregationcoef) || $data->aggregationcoef == '') {
$data->aggregationcoef = $defaults['aggregationcoef'];
}
if (!isset($data->weightoverride)) {
$data->weightoverride = $defaults['weightoverride'];
}
if (property_exists($data, 'calculation')) {
$data->calculation = grade_item::normalize_formula($data->calculation, $course->id);
}
$hidden = empty($data->hidden) ? 0: $data->hidden;
$hiddenuntil = empty($data->hiddenuntil) ? 0: $data->hiddenuntil;
unset($data->hidden);
unset($data->hiddenuntil);
$locked = empty($data->locked) ? 0: $data->locked;
$locktime = empty($data->locktime) ? 0: $data->locktime;
unset($data->locked);
unset($data->locktime);
$convert = array('gradepass', 'aggregationcoef', 'aggregationcoef2');
foreach ($convert as $param) {
if (property_exists($data, $param)) {
$data->$param = unformat_float($data->$param);
}
}
if (isset($data->aggregationcoef2) && $parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$data->aggregationcoef2 = $data->aggregationcoef2 / 100.0;
} else {
$data->aggregationcoef2 = $defaults['aggregationcoef2'];
}
$grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid));
grade_item::set_properties($grade_item, $data);
// fix activity links
if (empty($data->cmid)) {
// manual item
$grade_item->itemtype = 'manual';
$grade_item->itemmodule = null;
$grade_item->iteminstance = null;
$grade_item->itemnumber = 0;
} else {
$params = array($data->cmid);
$module = $DB->get_record_sql("SELECT cm.*, m.name as modname
FROM {modules} m, {course_modules} cm
WHERE cm.id = ? AND cm.module = m.id ", $params);
$grade_item->itemtype = 'mod';
$grade_item->itemmodule = $module->modname;
$grade_item->iteminstance = $module->instance;
if ($items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$grade_item->itemmodule,
'iteminstance'=>$grade_item->iteminstance, 'courseid'=>$COURSE->id))) {
if (!empty($grade_item->id) and in_array($grade_item, $items)) {
//no change needed
} else {
$max = 999;
foreach($items as $item) {
if (empty($item->outcomeid)) {
continue;
}
if ($item->itemnumber > $max) {
$max = $item->itemnumber;
}
}
$grade_item->itemnumber = $max + 1;
}
} else {
$grade_item->itemnumber = 1000;
}
}
// fix scale used
$outcome = grade_outcome::fetch(array('id'=>$data->outcomeid));
$grade_item->gradetype = GRADE_TYPE_SCALE;
$grade_item->scaleid = $outcome->scaleid; //TODO: we might recalculate existing outcome grades when changing scale
if (empty($grade_item->id)) {
$grade_item->insert();
// move next to activity if adding linked outcome
if ($grade_item->itemtype == 'mod') {
if ($item = grade_item::fetch(array('itemtype'=>'mod', 'itemmodule'=>$grade_item->itemmodule,
'iteminstance'=>$grade_item->iteminstance, 'itemnumber'=>0, 'courseid'=>$COURSE->id))) {
$grade_item->set_parent($item->categoryid);
$grade_item->move_after_sortorder($item->sortorder);
}
} else {
// set parent if needed
if (isset($data->parentcategory)) {
$grade_item->set_parent($data->parentcategory, false);
}
}
} else {
$grade_item->update();
}
// update hiding flag
if ($hiddenuntil) {
$grade_item->set_hidden($hiddenuntil, false);
} else {
$grade_item->set_hidden($hidden, false);
}
$grade_item->set_locktime($locktime); // locktime first - it might be removed when unlocking
$grade_item->set_locked($locked, false, true);
redirect($returnurl);
}
$PAGE->navbar->add($heading);
print_grade_page_head($courseid, 'settings', null, $heading, false, false, false);
if (!grade_outcome::fetch_all_available($COURSE->id)) {
echo $OUTPUT->confirm(get_string('nooutcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/course.php?id='.$courseid, $returnurl);
echo $OUTPUT->footer();
die();
}
$mform->display();
echo $OUTPUT->footer();
+266
View File
@@ -0,0 +1,266 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A moodleform to allow the creation and editing of outcome grade items
*
* @package core_grades
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once $CFG->libdir.'/formslib.php';
class edit_outcomeitem_form extends moodleform {
function definition() {
global $COURSE, $CFG;
$mform =& $this->_form;
/// visible elements
$mform->addElement('header', 'general', get_string('gradeoutcomeitem', 'grades'));
$mform->addElement('text', 'itemname', get_string('itemname', 'grades'));
$mform->addRule('itemname', get_string('required'), 'required', null, 'client');
$mform->setType('itemname', PARAM_TEXT);
$mform->addElement('text', 'iteminfo', get_string('iteminfo', 'grades'));
$mform->addHelpButton('iteminfo', 'iteminfo', 'grades');
$mform->setType('iteminfo', PARAM_TEXT);
$mform->addElement('text', 'idnumber', get_string('idnumbermod'));
$mform->addHelpButton('idnumber', 'idnumbermod');
$mform->setType('idnumber', PARAM_RAW);
// allow setting of outcomes on module items too
$options = array();
if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) {
foreach ($outcomes as $outcome) {
$options[$outcome->id] = $outcome->get_name();
}
}
$mform->addElement('selectwithlink', 'outcomeid', get_string('outcome', 'grades'), $options, null,
array('link' => $CFG->wwwroot.'/grade/edit/outcome/course.php?id='.$COURSE->id, 'label' => get_string('outcomeassigntocourse', 'grades')));
$mform->addHelpButton('outcomeid', 'outcome', 'grades');
$mform->addRule('outcomeid', get_string('required'), 'required');
$options = array(0=>get_string('none'));
if ($coursemods = get_course_mods($COURSE->id)) {
foreach ($coursemods as $coursemod) {
if ($mod = get_coursemodule_from_id($coursemod->modname, $coursemod->id)) {
$options[$coursemod->id] = format_string($mod->name);
}
}
}
$mform->addElement('select', 'cmid', get_string('linkedactivity', 'grades'), $options);
$mform->addHelpButton('cmid', 'linkedactivity', 'grades');
$mform->setDefault('cmid', 0);
/// hiding
/// advcheckbox is not compatible with disabledIf !!
$mform->addElement('checkbox', 'hidden', get_string('hidden', 'grades'));
$mform->addHelpButton('hidden', 'hidden', 'grades');
$mform->addElement('date_time_selector', 'hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
$mform->disabledIf('hidden', 'hiddenuntil[enabled]', 'checked');
//locking
$mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addHelpButton('locked', 'locked', 'grades');
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
/// parent category related settings
$mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
$mform->addElement('advcheckbox', 'weightoverride', get_string('adjustedweight', 'grades'));
$mform->addHelpButton('weightoverride', 'weightoverride', 'grades');
$mform->addElement('text', 'aggregationcoef2', get_string('weight', 'grades'));
$mform->addHelpButton('aggregationcoef2', 'weight', 'grades');
$mform->setType('aggregationcoef2', PARAM_RAW);
$mform->disabledIf('aggregationcoef2', 'weightoverride');
$options = array();
$default = '';
$coefstring = '';
$categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
foreach ($categories as $cat) {
$cat->apply_forced_settings();
$options[$cat->id] = $cat->get_name();
if ($cat->is_course_category()) {
$default = $cat->id;
}
if ($cat->is_aggregationcoef_used()) {
if ($cat->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefweight') ? 'aggregationcoefweight' : 'aggregationcoef';
} else if ($cat->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextrasum') ? 'aggregationcoefextrasum' : 'aggregationcoef';
} else if ($cat->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextraweight') ? 'aggregationcoefextraweight' : 'aggregationcoef';
} else if ($cat->aggregation == GRADE_AGGREGATE_SUM) {
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextrasum') ? 'aggregationcoefextrasum' : 'aggregationcoef';
} else {
$coefstring = 'aggregationcoef';
}
} else {
$mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $cat->id);
}
}
if (count($categories) > 1) {
$mform->addElement('select', 'parentcategory', get_string('gradecategory', 'grades'), $options);
$mform->disabledIf('parentcategory', 'cmid', 'noteq', 0);
}
if ($coefstring !== '') {
if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') {
// advcheckbox is not compatible with disabledIf!
$coefstring = 'aggregationcoefextrasum';
$mform->addElement('checkbox', 'aggregationcoef', get_string($coefstring, 'grades'));
} else {
$mform->addElement('text', 'aggregationcoef', get_string($coefstring, 'grades'));
}
$mform->addHelpButton('aggregationcoef', $coefstring, 'grades');
}
/// hidden params
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'courseid', $COURSE->id);
$mform->setType('courseid', PARAM_INT);
/// add return tracking info
$gpr = $this->_customdata['gpr'];
$gpr->add_mform_elements($mform);
//-------------------------------------------------------------------------------
// buttons
$this->add_action_buttons();
}
/// tweak the form - depending on existing data
function definition_after_data() {
global $CFG, $COURSE;
$mform =& $this->_form;
if ($id = $mform->getElementValue('id')) {
$grade_item = grade_item::fetch(array('id'=>$id));
//remove the aggregation coef element if not needed
if ($grade_item->is_course_item()) {
if ($mform->elementExists('parentcategory')) {
$mform->removeElement('parentcategory');
}
if ($mform->elementExists('aggregationcoef')) {
$mform->removeElement('aggregationcoef');
}
} else {
// if we wanted to change parent of existing item - we would have to verify there are no circular references in parents!!!
if ($mform->elementExists('parentcategory')) {
$mform->hardFreeze('parentcategory');
}
if ($grade_item->is_category_item()) {
$category = $grade_item->get_item_category();
$parent_category = $category->get_parent_category();
} else {
$parent_category = $grade_item->get_parent_category();
}
$parent_category->apply_forced_settings();
if (!$parent_category->is_aggregationcoef_used() || !$parent_category->aggregateoutcomes) {
if ($mform->elementExists('aggregationcoef')) {
$mform->removeElement('aggregationcoef');
}
} else {
//fix label if needed
$agg_el =& $mform->getElement('aggregationcoef');
$aggcoef = '';
if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
$aggcoef = 'aggregationcoefweight';
} else if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN2) {
$aggcoef = 'aggregationcoefextrasum';
} else if ($parent_category->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
$aggcoef = 'aggregationcoefextraweight';
} else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
$aggcoef = 'aggregationcoefextrasum';
}
if ($aggcoef !== '') {
$agg_el->setLabel(get_string($aggcoef, 'grades'));
$mform->addHelpButton('aggregationcoef', $aggcoef, 'grades');
}
}
// Remove the natural weighting fields for other aggregations,
// or when the category does not aggregate outcomes.
if ($parent_category->aggregation != GRADE_AGGREGATE_SUM ||
!$parent_category->aggregateoutcomes) {
if ($mform->elementExists('weightoverride')) {
$mform->removeElement('weightoverride');
}
if ($mform->elementExists('aggregationcoef2')) {
$mform->removeElement('aggregationcoef2');
}
}
}
}
// no parent header for course category
if (!$mform->elementExists('aggregationcoef') and !$mform->elementExists('parentcategory')) {
$mform->removeElement('headerparent');
}
}
/// perform extra validation before submission
function validation($data, $files) {
global $COURSE;
$errors = parent::validation($data, $files);
if (array_key_exists('idnumber', $data)) {
if ($data['id']) {
$grade_item = new grade_item(array('id'=>$data['id'], 'courseid'=>$data['courseid']));
} else {
$grade_item = null;
}
if (!grade_verify_idnumber($data['idnumber'], $COURSE->id, $grade_item, null)) {
$errors['idnumber'] = get_string('idnumbertaken');
}
}
return $errors;
}
}