diff --git a/admin/settings/grades.php b/admin/settings/grades.php index 2cb6122d508..84a5296dfde 100644 --- a/admin/settings/grades.php +++ b/admin/settings/grades.php @@ -96,11 +96,9 @@ if (has_capability('moodle/grade:manage', $systemcontext) GRADE_AGGREGATE_MODE =>new lang_string('aggregatemode', 'grades'), GRADE_AGGREGATE_SUM =>new lang_string('aggregatesum', 'grades')); - $defaultvisible = array(GRADE_AGGREGATE_MEAN, GRADE_AGGREGATE_WEIGHTED_MEAN, GRADE_AGGREGATE_WEIGHTED_MEAN2, - GRADE_AGGREGATE_EXTRACREDIT_MEAN, GRADE_AGGREGATE_MEDIAN, GRADE_AGGREGATE_MIN, - GRADE_AGGREGATE_MAX, GRADE_AGGREGATE_MODE, GRADE_AGGREGATE_SUM); + $defaultvisible = array(GRADE_AGGREGATE_SUM); - $defaults = array('value'=>GRADE_AGGREGATE_WEIGHTED_MEAN2, 'forced'=>false, 'adv'=>false); + $defaults = array('value' => GRADE_AGGREGATE_SUM, 'forced' => false, 'adv' => false); $temp->add(new admin_setting_gradecat_combo('grade_aggregation', new lang_string('aggregation', 'grades'), new lang_string('aggregation_help', 'grades'), $defaults, $options)); $temp->add(new admin_setting_configmultiselect('grade_aggregations_visible', new lang_string('aggregationsvisible', 'grades'), diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index e79c667b07a..4dd37be303c 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -940,8 +940,8 @@ class backup_gradebook_structure_step extends backup_structure_step { 'iteminstance', 'itemnumber', 'iteminfo', 'idnumber', 'calculation', 'gradetype', 'grademax', 'grademin', 'scaleid', 'outcomeid', 'gradepass', 'multfactor', - 'plusfactor', 'aggregationcoef', 'sortorder', 'display', - 'decimals', 'hidden', 'locked', 'locktime', + 'plusfactor', 'aggregationcoef', 'aggregationcoef2', 'weightoverride', + 'sortorder', 'display', 'decimals', 'hidden', 'locked', 'locktime', 'needsupdate', 'timecreated', 'timemodified')); $grade_grades = new backup_nested_element('grade_grades'); @@ -950,7 +950,8 @@ class backup_gradebook_structure_step extends backup_structure_step { 'rawscaleid', 'usermodified', 'finalgrade', 'hidden', 'locked', 'locktime', 'exported', 'overridden', 'excluded', 'feedback', 'feedbackformat', 'information', - 'informationformat', 'timecreated', 'timemodified')); + 'informationformat', 'timecreated', 'timemodified', + 'aggregationstatus', 'aggregationweight')); //grade_categories $grade_categories = new backup_nested_element('grade_categories'); @@ -2163,8 +2164,8 @@ class backup_activity_grades_structure_step extends backup_structure_step { 'iteminstance', 'itemnumber', 'iteminfo', 'idnumber', 'calculation', 'gradetype', 'grademax', 'grademin', 'scaleid', 'outcomeid', 'gradepass', 'multfactor', - 'plusfactor', 'aggregationcoef', 'sortorder', 'display', - 'decimals', 'hidden', 'locked', 'locktime', + 'plusfactor', 'aggregationcoef', 'aggregationcoef2', 'weightoverride', + 'sortorder', 'display', 'decimals', 'hidden', 'locked', 'locktime', 'needsupdate', 'timecreated', 'timemodified')); $grades = new backup_nested_element('grade_grades'); @@ -2174,7 +2175,8 @@ class backup_activity_grades_structure_step extends backup_structure_step { 'rawscaleid', 'usermodified', 'finalgrade', 'hidden', 'locked', 'locktime', 'exported', 'overridden', 'excluded', 'feedback', 'feedbackformat', 'information', - 'informationformat', 'timecreated', 'timemodified')); + 'informationformat', 'timecreated', 'timemodified', + 'aggregationstatus', 'aggregationweight')); $letters = new backup_nested_element('grade_letters'); diff --git a/grade/edit/scale/edit.php b/grade/edit/scale/edit.php index 04373b19912..e0165603626 100644 --- a/grade/edit/scale/edit.php +++ b/grade/edit/scale/edit.php @@ -32,6 +32,8 @@ $id = optional_param('id', 0, PARAM_INT); $PAGE->set_url('/grade/edit/scale/edit.php', array('id' => $id, 'courseid' => $courseid)); $PAGE->set_pagelayout('admin'); +navigation_node::override_active_url(new moodle_url('/grade/edit/scale/index.php', + array('id' => $courseid))); $systemcontext = context_system::instance(); $heading = ''; @@ -145,11 +147,7 @@ if ($mform->is_cancelled()) { redirect($returnurl); } -if ($courseid) { - print_grade_page_head($course->id, 'scale', 'edit', $heading); -} else { - echo $OUTPUT->header(); -} +print_grade_page_head($COURSE->id, 'scale', null, $heading, false, false, false); $mform->display(); diff --git a/grade/edit/settings/index.php b/grade/edit/settings/index.php index fa7a81f6361..3baacc7935d 100644 --- a/grade/edit/settings/index.php +++ b/grade/edit/settings/index.php @@ -45,8 +45,6 @@ $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'settings', 'cour $strgrades = get_string('grades'); $pagename = get_string('coursesettings', 'grades'); -$navigation = grade_build_nav(__FILE__, $pagename, $courseid); - $returnurl = $CFG->wwwroot.'/grade/index.php?id='.$course->id; $mform = new course_settings_form(); @@ -76,7 +74,7 @@ if ($mform->is_cancelled()) { redirect($returnurl); } -print_grade_page_head($courseid, 'settings', 'coursesettings', get_string('coursesettings', 'grades')); +print_grade_page_head($courseid, 'settings', 'coursesettings', get_string('coursegradesettings', 'grades')); echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthnormal centerpara'); echo get_string('coursesettingsexplanation', 'grades'); diff --git a/grade/edit/tree/action.php b/grade/edit/tree/action.php index f8d18f32599..cea87915708 100644 --- a/grade/edit/tree/action.php +++ b/grade/edit/tree/action.php @@ -107,6 +107,37 @@ switch ($action) { $object->set_locked(0, true, 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)) { + print_error('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); diff --git a/grade/edit/tree/calculation.php b/grade/edit/tree/calculation.php index bd275513d8a..e0dabcf861a 100644 --- a/grade/edit/tree/calculation.php +++ b/grade/edit/tree/calculation.php @@ -46,6 +46,10 @@ 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); @@ -109,10 +113,8 @@ $strgrades = get_string('grades'); $strgraderreport = get_string('graderreport', 'grades'); $strcalculationedit = get_string('editcalculation', 'grades'); -grade_build_nav(__FILE__, $strcalculationedit, array('courseid' => $courseid)); -$PAGE->set_title($strgrades . ': ' . $strgraderreport); -$PAGE->set_heading($course->fullname); -echo $OUTPUT->header(); +$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 diff --git a/grade/edit/tree/category.php b/grade/edit/tree/category.php index 852fdd55206..206b12de92d 100644 --- a/grade/edit/tree/category.php +++ b/grade/edit/tree/category.php @@ -36,6 +36,8 @@ if ($id !== 0) { } $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))) { print_error('nocourseid'); @@ -75,6 +77,7 @@ if ($id) { $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 @@ -84,6 +87,16 @@ if ($id) { $category->grade_item_aggregationcoef = format_float($category->grade_item_aggregationcoef, 4); } + 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 { $heading = get_string('newcategory', 'grades'); $grade_category = new grade_category(array('courseid'=>$courseid), false); @@ -160,12 +173,15 @@ if ($mform->is_cancelled()) { unset($itemdata->locked); unset($itemdata->locktime); - $convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef'); + $convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef', 'aggregationcoef2'); foreach ($convert as $param) { if (property_exists($itemdata, $param)) { $itemdata->$param = unformat_float($itemdata->$param); } } + if (isset($itemdata->aggregationcoef2)) { + $itemdata->aggregationcoef2 = $itemdata->aggregationcoef2 / 100.0; + } // When creating a new category, a number of grade item fields are filled out automatically, and are required. // If the user leaves these fields empty during creation of a category, we let the default values take effect @@ -195,6 +211,14 @@ if ($mform->is_cancelled()) { $grade_item->decimals = null; } + // Change weightoverride flag. Check if the value is set, because it is not when the checkbox is not ticked. + $itemdata->weightoverride = isset($itemdata->weightoverride) ? $itemdata->weightoverride : 0; + if ($grade_item->weightoverride != $itemdata->weightoverride && $grade_category->aggregation == GRADE_AGGREGATE_SUM) { + // If we are using natural weight and the weight has been un-overriden, force parent category to recalculate weights. + $grade_category->force_regrading(); + } + $grade_item->weightoverride = $itemdata->weightoverride; + $grade_item->outcomeid = null; // update hiding flag @@ -217,10 +241,8 @@ if ($mform->is_cancelled()) { redirect($returnurl); } -$return = false; -$buttons = false; -$shownavigation = false; -print_grade_page_head($courseid, 'edittree', null, $heading, $return, $buttons, $shownavigation); +$PAGE->navbar->add($heading); +print_grade_page_head($courseid, 'settings', null, $heading, false, false, false); $mform->display(); diff --git a/grade/edit/tree/category_form.php b/grade/edit/tree/category_form.php index f893091e8d4..6a155fded5d 100644 --- a/grade/edit/tree/category_form.php +++ b/grade/edit/tree/category_form.php @@ -37,15 +37,7 @@ class edit_category_form extends moodleform { $category = $this->_customdata['current']; - $this->aggregation_options = array(GRADE_AGGREGATE_MEAN =>get_string('aggregatemean', 'grades'), - GRADE_AGGREGATE_WEIGHTED_MEAN =>get_string('aggregateweightedmean', 'grades'), - GRADE_AGGREGATE_WEIGHTED_MEAN2 =>get_string('aggregateweightedmean2', 'grades'), - GRADE_AGGREGATE_EXTRACREDIT_MEAN=>get_string('aggregateextracreditmean', 'grades'), - GRADE_AGGREGATE_MEDIAN =>get_string('aggregatemedian', 'grades'), - GRADE_AGGREGATE_MIN =>get_string('aggregatemin', 'grades'), - GRADE_AGGREGATE_MAX =>get_string('aggregatemax', 'grades'), - GRADE_AGGREGATE_MODE =>get_string('aggregatemode', 'grades'), - GRADE_AGGREGATE_SUM =>get_string('aggregatesum', 'grades')); + $this->aggregation_options = grade_helper::get_aggregation_strings(); // visible elements $mform->addElement('header', 'headercategory', get_string('gradecategory', 'grades')); @@ -62,7 +54,6 @@ class edit_category_form extends moodleform { $mform->addElement('checkbox', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades')); $mform->addHelpButton('aggregateonlygraded', 'aggregateonlygraded', 'grades'); - $mform->disabledIf('aggregateonlygraded', 'aggregation', 'eq', GRADE_AGGREGATE_SUM); if ((int)$CFG->grade_aggregateonlygraded_flag & 2) { $mform->setAdvanced('aggregateonlygraded'); @@ -170,6 +161,14 @@ class edit_category_form extends moodleform { $mform->disabledIf('grade_item_grademin', 'aggregation', 'eq', GRADE_AGGREGATE_SUM); } + $mform->addElement('advcheckbox', 'grade_item_weightoverride', get_string('adjustedweight', 'grades')); + $mform->addHelpButton('grade_item_weightoverride', 'weightoverride', 'grades'); + + $mform->addElement('text', 'grade_item_aggregationcoef2', get_string('weight', 'grades')); + $mform->addHelpButton('grade_item_aggregationcoef2', 'weight', 'grades'); + $mform->setType('grade_item_aggregationcoef2', PARAM_RAW); + $mform->disabledIf('grade_item_aggregationcoef2', 'grade_item_weightoverride'); + $mform->addElement('text', 'grade_item_gradepass', get_string('gradepass', 'grades')); $mform->setType('grade_item_gradepass', PARAM_RAW); $mform->addHelpButton('grade_item_gradepass', 'gradepass', 'grades'); @@ -332,6 +331,18 @@ class edit_category_form extends moodleform { } + // 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')) { @@ -430,6 +441,12 @@ class edit_category_form extends moodleform { $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(); @@ -448,8 +465,9 @@ class edit_category_form extends moodleform { $coefstring = $grade_item->get_coefstring(); - if ($coefstring == 'aggregationcoefextrasum') { + 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')); @@ -457,6 +475,16 @@ class edit_category_form extends moodleform { $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. + if ($parent_category->aggregation != GRADE_AGGREGATE_SUM) { + if ($mform->elementExists('grade_item_weightoverride')) { + $mform->removeElement('grade_item_weightoverride'); + } + if ($mform->elementExists('grade_item_aggregationcoef2')) { + $mform->removeElement('grade_item_aggregationcoef2'); + } + } } } } diff --git a/grade/edit/tree/functions.js b/grade/edit/tree/functions.js index 5649ea22d70..2da2f011658 100644 --- a/grade/edit/tree/functions.js +++ b/grade/edit/tree/functions.js @@ -69,6 +69,18 @@ function update_category_aggregation(e, args) { window.location = 'index.php?id='+args.courseid+'&category='+args.category+'&aggregationtype='+selectmenu.get('value')+'&sesskey='+args.sesskey; } +/** + * The weight override checkboxes toggle the disabled status of their associated weight fields. + */ +YUI().use('node', 'delegate', function(Y) { + Y.on('domready', function() { + Y.delegate('click', function(e) { + var t = e.currentTarget, + itemid = t.get('id').split('_')[1]; + Y.one('input[name=weight_' + itemid + ']').set('disabled', t.get('checked') ? false : true); + }, Y.config.doc.body, 'input.weightoverride'); + }); +}); /* TODO: finish and rewrite for YUI3... Y.YUI2.namespace('grade_edit_tree'); diff --git a/grade/edit/tree/grade_form.php b/grade/edit/tree/grade_form.php index 06e51624b97..be8a0a69a22 100644 --- a/grade/edit/tree/grade_form.php +++ b/grade/edit/tree/grade_form.php @@ -85,11 +85,7 @@ class edit_grade_form extends moodleform { $mform->disabledIf('finalgrade', 'overridden', 'notchecked'); } - if ($grade_category and $grade_category->aggregation == GRADE_AGGREGATE_SUM) { - $mform->addElement('advcheckbox', 'excluded', get_string('excluded', 'grades'), '('.get_string('warningexcludedsum', 'grades').')'); - } else { - $mform->addElement('advcheckbox', 'excluded', get_string('excluded', 'grades')); - } + $mform->addElement('advcheckbox', 'excluded', get_string('excluded', 'grades')); $mform->addHelpButton('excluded', 'excluded', 'grades'); /// hiding diff --git a/grade/edit/tree/index.php b/grade/edit/tree/index.php index 68bb267666d..849c23b58a5 100644 --- a/grade/edit/tree/index.php +++ b/grade/edit/tree/index.php @@ -32,12 +32,8 @@ $action = optional_param('action', 0, PARAM_ALPHA); $eid = optional_param('eid', 0, PARAM_ALPHANUM); $category = optional_param('category', null, PARAM_INT); $aggregationtype = optional_param('aggregationtype', null, PARAM_INT); -$showadvanced = optional_param('showadvanced', -1, PARAM_BOOL); // sticky editing mode $url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid)); -if($showadvanced!=-1) { - $url->param("showadvanced",$showadvanced); -} $PAGE->set_url($url); $PAGE->set_pagelayout('admin'); @@ -57,41 +53,6 @@ $PAGE->requires->js('/grade/edit/tree/functions.js'); $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid)); $returnurl = $gpr->get_return_url(null); -/// Build editing on/off buttons -if (!isset($USER->gradeediting)) { - $USER->gradeediting = array(); -} - -$current_view = ''; - -if (has_capability('moodle/grade:manage', $context)) { - if (!isset($USER->gradeediting[$course->id])) { - $USER->gradeediting[$course->id] = 0; - } - - if ($showadvanced == 1) { - $USER->gradeediting[$course->id] = 1; - } else if ($showadvanced == 0) { - $USER->gradeediting[$course->id] = 0; - } - - // page params for the turn editing on - $options = $gpr->get_options(); - $options['sesskey'] = sesskey(); - - if ($USER->gradeediting[$course->id]) { - $options['showadvanced'] = 0; - $current_view = 'fullview'; - } else { - $options['showadvanced'] = 1; - $current_view = 'simpleview'; - } - -} else { - $USER->gradeediting[$course->id] = 0; - $buttons = ''; -} - // Change category aggregation if requested if (!is_null($category) && !is_null($aggregationtype) && confirm_sesskey()) { if (!$grade_category = grade_category::fetch(array('id'=>$category, 'courseid'=>$courseid))) { @@ -107,8 +68,18 @@ if (!is_null($category) && !is_null($aggregationtype) && confirm_sesskey()) { } //first make sure we have proper final grades - we need it for locking changes +$normalisationmessage = null; + +$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid); + grade_regrade_final_grades($courseid); +$alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid); + +if (array_diff($originalweights, $alteredweights)) { + $normalisationmessage = get_string('weightsadjusted', 'grades'); +} + // 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); @@ -128,8 +99,6 @@ $switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggr $strgrades = get_string('grades'); $strgraderreport = get_string('graderreport', 'grades'); -$strcategoriesedit = get_string('categoriesedit', 'grades'); -$strcategoriesanditems = get_string('categoriesanditems', 'grades'); $moving = false; $movingeid = false; @@ -206,21 +175,6 @@ switch ($action) { break; } -// Hide advanced columns if moving -if ($grade_edit_tree->moving) { - $original_gradeediting = $USER->gradeediting[$course->id]; - $USER->gradeediting[$course->id] = 0; -} - -$current_view_str = ''; -if ($current_view != '') { - if ($current_view == 'simpleview') { - $current_view_str = get_string('simpleview', 'grades'); - } elseif ($current_view == 'fullview') { - $current_view_str = get_string('fullview', 'grades'); - } -} - //if we go straight to the db to update an element we need to recreate the tree as // $grade_edit_tree has already been constructed. //Ideally we could do the updates through $grade_edit_tree to avoid recreating it @@ -232,7 +186,7 @@ if ($data = data_submitted() and confirm_sesskey()) { $elements = array(); foreach ($data as $key => $value) { - if (preg_match('/select_(i[0-9]*)/', $key, $matches)) { + if (preg_match('/select_(ig[0-9]*)/', $key, $matches)) { $elements[] = $matches[1]; } } @@ -240,77 +194,57 @@ if ($data = data_submitted() and confirm_sesskey()) { $grade_edit_tree->move_elements($elements, $returnurl); } - // Category and item field updates + // Update weights (extra credits) on categories and items. foreach ($data as $key => $value) { - // Grade category text inputs - if (preg_match('/^(aggregation|droplow|keephigh)_([0-9]+)$/', $key, $matches)) { - $param = $matches[1]; - $aid = $matches[2]; - - // Do not allow negative values - $value = clean_param($value, PARAM_INT); - $value = ($value < 0) ? 0 : $value; - - $grade_category = grade_category::fetch(array('id'=>$aid, 'courseid'=>$courseid)); - $grade_category->$param = $value; - - $grade_category->update(); - grade_regrade_final_grades($courseid); - - $recreatetree = true; - - // Grade item text inputs - } elseif (preg_match('/^(grademax|aggregationcoef|multfactor|plusfactor)_([0-9]+)$/', $key, $matches)) { - $param = $matches[1]; - $aid = $matches[2]; + 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)); + $grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid)); - if ($param === 'grademax' and $value < $grade_item->grademin) { - // better not allow values lower than grade min - $value = $grade_item->grademin; + // 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(); - grade_regrade_final_grades($courseid); - - $recreatetree = true; - - // Grade item checkbox inputs - } elseif (preg_match('/^extracredit_([0-9]+)$/', $key, $matches)) { // Sum extra credit checkbox - $aid = $matches[1]; - $value = clean_param($value, PARAM_BOOL); - - $grade_item = grade_item::fetch(array('id'=>$aid, 'courseid'=>$courseid)); - $grade_item->aggregationcoef = $value; - - $grade_item->update(); - grade_regrade_final_grades($courseid); - - $recreatetree = true; - - // Grade category checkbox inputs - } elseif (preg_match('/^aggregate(onlygraded|subcats|outcomes)_([0-9]+)$/', $key, $matches)) { - $param = 'aggregate'.$matches[1]; - $aid = $matches[2]; - $value = clean_param($value, PARAM_BOOL); - - $grade_category = grade_category::fetch(array('id'=>$aid, 'courseid'=>$courseid)); - $grade_category->$param = $value; - - $grade_category->update(); - grade_regrade_final_grades($courseid); $recreatetree = true; } } + + $originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid); + + grade_regrade_final_grades($courseid); + + $alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid); + if (array_diff($originalweights, $alteredweights)) { + $normalisationmessage = get_string('weightsadjusted', 'grades'); + } } -print_grade_page_head($courseid, 'edittree', $current_view, get_string('categoriesedit', 'grades') . ': ' . $current_view_str); +print_grade_page_head($courseid, 'settings', 'setup', get_string('setupgradeslayout', 'grades')); // Print Table of categories and items echo $OUTPUT->box_start('gradetreebox generalbox'); @@ -323,6 +257,10 @@ echo ''; if ($recreatetree) { $grade_edit_tree = new grade_edit_tree($gtree, $movingeid, $gpr); } +// Check to see if we have a normalisation message to send. +if (!empty($normalisationmessage)) { + echo $OUTPUT->notification($normalisationmessage, 'notifymessage'); +} echo html_writer::table($grade_edit_tree->table); @@ -377,11 +315,6 @@ $PAGE->requires->yui_module('moodle-core-formchangechecker', $PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle'); echo $OUTPUT->footer(); - -// Restore original show/hide preference if moving -if ($moving) { - $USER->gradeediting[$course->id] = $original_gradeediting; -} die; diff --git a/grade/edit/tree/item.php b/grade/edit/tree/item.php index 7acf2ebe17d..acbf5812a71 100644 --- a/grade/edit/tree/item.php +++ b/grade/edit/tree/item.php @@ -37,6 +37,8 @@ if ($id !== 0) { } $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))) { print_error('nocourseid'); @@ -97,6 +99,9 @@ if ($parent_category->aggregation == GRADE_AGGREGATE_SUM or $parent_category->ag } 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)); @@ -132,12 +137,15 @@ if ($mform->is_cancelled()) { unset($data->locked); unset($data->locktime); - $convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef'); + $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; + } $grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid)); grade_item::set_properties($grade_item, $data); @@ -174,10 +182,8 @@ if ($mform->is_cancelled()) { redirect($returnurl); } -$return = false; -$buttons = false; -$shownavigation = false; -print_grade_page_head($courseid, 'edittree', null, $heading, $return, $buttons, $shownavigation); +$PAGE->navbar->add($heading); +print_grade_page_head($courseid, 'settings', null, $heading, false, false, false); $mform->display(); diff --git a/grade/edit/tree/item_form.php b/grade/edit/tree/item_form.php index 13ad68703c9..a74120fdc0c 100644 --- a/grade/edit/tree/item_form.php +++ b/grade/edit/tree/item_form.php @@ -97,6 +97,14 @@ class edit_item_form extends moodleform { $mform->setType('grademin', PARAM_RAW); } + $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'); + $mform->addElement('text', 'gradepass', get_string('gradepass', 'grades')); $mform->addHelpButton('gradepass', 'gradepass', 'grades'); $mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_NONE); @@ -278,8 +286,9 @@ class edit_item_form extends moodleform { $coefstring = $grade_item->get_coefstring(); if ($coefstring !== '') { - if ($coefstring == 'aggregationcoefextrasum') { + if ($coefstring == 'aggregationcoefextrasum' || $coefstring == 'aggregationcoefextraweightsum') { // 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')); @@ -295,6 +304,16 @@ class edit_item_form extends moodleform { $mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $parent_category->id); } + // Remove fields used by natural weighting if the parent category is not using natural weighting. + if ($parent_category->aggregation != GRADE_AGGREGATE_SUM) { + if ($mform->elementExists('weightoverride')) { + $mform->removeElement('weightoverride'); + } + if ($mform->elementExists('aggregationcoef2')) { + $mform->removeElement('aggregationcoef2'); + } + } + if ($category = $grade_item->get_item_category()) { if ($category->aggregation == GRADE_AGGREGATE_SUM) { if ($mform->elementExists('gradetype')) { diff --git a/grade/edit/tree/lib.php b/grade/edit/tree/lib.php index c483ff25986..177fdb44af4 100644 --- a/grade/edit/tree/lib.php +++ b/grade/edit/tree/lib.php @@ -42,10 +42,11 @@ class grade_edit_tree { public $deepest_level; - public $uses_extra_credit = false; - public $uses_weight = false; + /** @var bool indicates if tree has categories with aggregation method other than Natural. */ + protected $uses_non_natural = false; + public $table; public $categories = array(); @@ -70,42 +71,32 @@ class grade_edit_tree { $this->gpr = $gpr; $this->deepest_level = $this->get_deepest_level($this->gtree->top_element); - $this->columns = array(grade_edit_tree_column::factory('name', array('deepest_level' => $this->deepest_level)), - grade_edit_tree_column::factory('aggregation', array('flag' => true))); + $this->columns = array(grade_edit_tree_column::factory('name', array('deepest_level' => $this->deepest_level))); + + if ($this->uses_non_natural) { + $this->columns[] = grade_edit_tree_column::factory('aggregation', array('flag' => true)); + } if ($this->uses_weight) { - $this->columns[] = grade_edit_tree_column::factory('weight', array('adv' => 'aggregationcoef')); - } - if ($this->uses_extra_credit) { - $this->columns[] = grade_edit_tree_column::factory('extracredit', array('adv' => 'aggregationcoef')); + $this->columns[] = grade_edit_tree_column::factory('weight', array('adv' => 'weight')); } $this->columns[] = grade_edit_tree_column::factory('range'); // This is not a setting... How do we deal with it? - $this->columns[] = grade_edit_tree_column::factory('aggregateonlygraded', array('flag' => true)); - $this->columns[] = grade_edit_tree_column::factory('aggregatesubcats', array('flag' => true)); - $this->columns[] = grade_edit_tree_column::factory('aggregateoutcomes', array('flag' => true)); - $this->columns[] = grade_edit_tree_column::factory('droplow', array('flag' => true)); - $this->columns[] = grade_edit_tree_column::factory('keephigh', array('flag' => true)); - $this->columns[] = grade_edit_tree_column::factory('multfactor', array('adv' => true)); - $this->columns[] = grade_edit_tree_column::factory('plusfactor', array('adv' => true)); $this->columns[] = grade_edit_tree_column::factory('actions'); - $this->columns[] = grade_edit_tree_column::factory('select'); - $mode = ($USER->gradeediting[$COURSE->id]) ? 'advanced' : 'simple'; - - $widthstyle = ''; - if ($mode == 'simple') { - $widthstyle = ' style="width:auto;" '; + if ($this->deepest_level > 1) { + $this->columns[] = grade_edit_tree_column::factory('select'); } $this->table = new html_table(); $this->table->id = "grade_edit_tree_table"; - $this->table->cellpadding = 5; - $this->table->attributes['class'] = 'generaltable ' . $mode; - $this->table->style = $widthstyle; + $this->table->attributes['class'] = 'generaltable simple setup-grades'; + if ($this->moving) { + $this->table->attributes['class'] .= ' moving'; + } foreach ($this->columns as $column) { - if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) { + if (!($this->moving && $column->hide_when_moving)) { $this->table->head[] = $column->get_header_cell(); } } @@ -143,6 +134,7 @@ class grade_edit_tree { } $actions = ''; + $moveaction = ''; if (!$is_category_item) { $actions .= $this->gtree->get_edit_icon($element, $this->gpr); @@ -159,13 +151,12 @@ class grade_edit_tree { } $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'moveselect', 'eid' => $eid, 'sesskey' => sesskey())); - $actions .= $OUTPUT->action_icon($aurl, new pix_icon('t/move', get_string('move'))); + $moveaction .= $OUTPUT->action_icon($aurl, new pix_icon('t/move', get_string('move'))); } $actions .= $this->gtree->get_hiding_icon($element, $this->gpr); - $actions .= $this->gtree->get_locking_icon($element, $this->gpr); - $mode = ($USER->gradeediting[$COURSE->id]) ? 'advanced' : 'simple'; + $actions .= $this->gtree->get_reset_icon($element, $this->gpr); $returnrows = array(); $root = false; @@ -180,7 +171,8 @@ class grade_edit_tree { // do not diplay children $cell = new html_table_cell(); $cell->colspan = 12; - $cell->attributes['class'] = $element['type'] . ' moving'; + $cell->attributes['class'] = $element['type'] . ' moving column-name level' . + ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd'); $cell->text = $object->name.' ('.get_string('move').')'; return array(new html_table_row(array($cell))); } @@ -225,7 +217,7 @@ class grade_edit_tree { $strmove = get_string('move'); $strmovehere = get_string('movehere'); - $actions = ''; // no action icons when moving + $actions = $moveaction = ''; // no action icons when moving $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'move', 'eid' => $this->moving, 'moveafter' => $child_eid, 'sesskey' => sesskey())); if ($first) { @@ -234,6 +226,7 @@ class grade_edit_tree { $cell = new html_table_cell(); $cell->colspan = 12; + $cell->attributes['class'] = 'movehere level' . ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd'); $icon = new pix_icon('movehere', $strmovehere, null, array('class'=>'movetarget')); $cell->text = $OUTPUT->action_icon($aurl, $icon); @@ -285,7 +278,7 @@ class grade_edit_tree { $root = true; } - $levelclass = "level$level"; + $levelclass = "level$level level" . ($level % 2 ? 'odd' : 'even'); $courseclass = ''; if ($level == 1) { @@ -302,13 +295,15 @@ class grade_edit_tree { $headercell->header = true; $headercell->scope = 'row'; $headercell->attributes['title'] = $object->stripped_name; - $headercell->attributes['class'] = 'cell rowspan ' . $levelclass; + $headercell->attributes['class'] = 'cell column-rowspan rowspan ' . $levelclass; $headercell->rowspan = $row_count + 1; $row->cells[] = $headercell; foreach ($this->columns as $column) { - if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) { - $row->cells[] = $column->get_category_cell($category, $levelclass, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'eid' => $eid)); + if (!($this->moving && $column->hide_when_moving)) { + $row->cells[] = $column->get_category_cell($category, $levelclass, array('id' => $id, + 'name' => $object->name, 'level' => $level, 'actions' => $actions, + 'moveaction' => $moveaction, 'eid' => $eid)); } } @@ -319,7 +314,7 @@ class grade_edit_tree { // Print a coloured row to show the end of the category across the table $endcell = new html_table_cell(); $endcell->colspan = (19 - $level); - $endcell->attributes['class'] = 'colspan ' . $levelclass; + $endcell->attributes['class'] = 'emptyrow colspan ' . $levelclass; $returnrows[] = new html_table_row(array($endcell)); @@ -333,6 +328,9 @@ class grade_edit_tree { if ($item->itemtype == 'category') { $categoryitemclass = 'categoryitem'; } + if ($item->itemtype == 'course') { + $categoryitemclass = 'courseitem'; + } $dimmed = ($item->is_hidden()) ? "dimmed_text" : ""; $gradeitemrow = new html_table_row(); @@ -342,9 +340,10 @@ class grade_edit_tree { } foreach ($this->columns as $column) { - if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) { - $gradeitemrow->cells[] = $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, - 'element' => $element, 'eid' => $eid, 'itemtype' => $object->itemtype)); + if (!($this->moving && $column->hide_when_moving)) { + $gradeitemrow->cells[] = $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, + 'level' => $level, 'actions' => $actions, 'element' => $element, 'eid' => $eid, + 'moveaction' => $moveaction, 'itemtype' => $object->itemtype)); } } @@ -358,10 +357,9 @@ class grade_edit_tree { /** * Given a grade_item object, returns a labelled input if an aggregation coefficient (weight or extra credit) applies to it. * @param grade_item $item - * @param string type "extra" or "weight": the type of the column hosting the weight input * @return string HTML */ - static function get_weight_input($item, $type) { + static function get_weight_input($item) { global $OUTPUT; if (!is_object($item) || get_class($item) !== 'grade_item') { @@ -377,21 +375,60 @@ class grade_edit_tree { $parent_category->apply_forced_settings(); $aggcoef = $item->get_coefstring(); - if ((($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoef') && $type == 'weight') || - ($aggcoef == 'aggregationcoefextraweight' && $type == 'extra')) { - return ''. - ''; - } elseif ($aggcoef == 'aggregationcoefextrasum' && $type == 'extra') { - $checked = ($item->aggregationcoef > 0) ? 'checked="checked"' : ''; - return ' - - \n"; - } else { - return ''; + $itemname = $item->itemname; + if ($item->is_category_item()) { + // Remember, the parent category of a category item is the category itself. + $itemname = $parent_category->get_name(); } + $str = ''; + + if ($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoef' || $aggcoef == 'aggregationcoefextraweight') { + return ''. + ''; + } else if ($aggcoef == 'aggregationcoefextraweightsum') { + + $checkboxname = 'weightoverride_' . $item->id; + $checkboxlbl = html_writer::tag('label', get_string('overrideweightofa', 'grades', $itemname), + array('for' => $checkboxname, 'class' => 'accesshide')); + $checkbox = html_writer::empty_tag('input', array('name' => $checkboxname, + 'type' => 'hidden', 'value' => 0)); + $checkbox .= html_writer::empty_tag('input', array('name' => $checkboxname, + 'type' => 'checkbox', 'value' => 1, 'id' => $checkboxname, 'class' => 'weightoverride', + 'checked' => ($item->weightoverride ? 'checked' : null))); + + $name = 'weight_' . $item->id; + $hiddenlabel = html_writer::tag( + 'label', + get_string('weightofa', 'grades', $itemname), + array( + 'class' => 'accesshide', + 'for' => $name + ) + ); + + $input = html_writer::empty_tag( + 'input', + array( + 'type' => 'text', + 'size' => 6, + 'id' => $name, + 'name' => $name, + 'value' => grade_edit_tree::format_number($item->aggregationcoef2 * 100.0), + 'disabled' => ($item->weightoverride ? null : 'disabled') + ) + ); + + $str .= $checkboxlbl . $checkbox . $hiddenlabel . $input; + + if ($item->aggregationcoef > 0) { + $str .= ' ' . html_writer::tag('abbr', get_string('aggregationcoefextrasumabbr', 'grades'), + array('title' => get_string('aggregationcoefextrasum', 'grades'))); + } + } + + return $str; } //Trims trailing zeros @@ -448,7 +485,7 @@ class grade_edit_tree { $eids = array($eids); } - if(!$after_el = $this->gtree->locate_element("c$moveafter")) { + if(!$after_el = $this->gtree->locate_element("cg$moveafter")) { print_error('invalidelementid', '', $returnurl); } @@ -486,10 +523,13 @@ class grade_edit_tree { $level++; $coefstring = $element['object']->get_coefstring(); if ($element['type'] == 'category') { - if ($coefstring == 'aggregationcoefweight') { + if ($element['object']->aggregation != GRADE_AGGREGATE_SUM) { + $this->uses_non_natural = true; + } + + if ($coefstring == 'aggregationcoefweight' || $coefstring == 'aggregationcoefextraweightsum' || + $coefstring == 'aggregationcoefextraweight') { $this->uses_weight = true; - } elseif ($coefstring == 'aggregationcoefextraweight' || $coefstring == 'aggregationcoefextrasum') { - $this->uses_extra_credit = true; } foreach($element['children'] as $child_el) { @@ -504,6 +544,12 @@ class grade_edit_tree { } } +/** + * Class grade_edit_tree_column + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ abstract class grade_edit_tree_column { public $forced; public $hidden; @@ -538,16 +584,27 @@ abstract class grade_edit_tree_column { public abstract function get_header_cell(); - public abstract function get_category_cell($category, $levelclass, $params); + public function get_category_cell($category, $levelclass, $params) { + $cell = clone($this->categorycell); + $cell->attributes['class'] .= ' ' . $levelclass; + $cell->attributes['text'] = ''; + return $cell; + } - public abstract function get_item_cell($item, $params); - - public abstract function is_hidden($mode='simple'); + public function get_item_cell($item, $params) { + $cell = clone($this->itemcell); + $cell->attributes['text'] = ''; + if (isset($params['level'])) { + $level = $params['level'] + (($item->itemtype == 'category' || $item->itemtype == 'course') ? 0 : 1); + $cell->attributes['class'] .= ' level' . $level; + $cell->attributes['class'] .= ' level' . ($level % 2 ? 'odd' : 'even'); + } + return $cell; + } public function __construct() { $this->headercell = new html_table_cell(); $this->headercell->header = true; - $this->headercell->style = 'whitespace: normal;'; $this->headercell->attributes['class'] = 'header'; $this->categorycell = new html_table_cell(); @@ -555,35 +612,21 @@ abstract class grade_edit_tree_column { $this->itemcell = new html_table_cell(); $this->itemcell->attributes['class'] = 'cell'; - } -} -abstract class grade_edit_tree_column_category extends grade_edit_tree_column { - - public $forced; - public $advanced; - - public function __construct($name) { - global $CFG; - $this->forced = (int)$CFG->{"grade_$name"."_flag"} & 1; - $this->advanced = (int)$CFG->{"grade_$name"."_flag"} & 2; - parent::__construct(); - } - - public function is_hidden($mode='simple') { - global $CFG; - if ($mode == 'simple') { - return $this->advanced; - } elseif ($mode == 'advanced') { - if ($this->forced && $CFG->grade_hideforcedsettings) { - return true; - } else { - return false; - } + if (preg_match('/^grade_edit_tree_column_(\w*)$/', get_class($this), $matches)) { + $this->headercell->attributes['class'] .= ' column-' . $matches[1]; + $this->categorycell->attributes['class'] .= ' column-' . $matches[1]; + $this->itemcell->attributes['class'] .= ' column-' . $matches[1]; } } } +/** + * Class grade_edit_tree_column_name + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class grade_edit_tree_column_name extends grade_edit_tree_column { public $forced = false; public $hidden = false; @@ -603,7 +646,6 @@ class grade_edit_tree_column_name extends grade_edit_tree_column { public function get_header_cell() { $headercell = clone($this->headercell); - $headercell->attributes['class'] .= ' name'; $headercell->colspan = $this->deepest_level + 1; $headercell->text = get_string('name'); return $headercell; @@ -614,10 +656,10 @@ class grade_edit_tree_column_name extends grade_edit_tree_column { if (empty($params['name']) || empty($params['level'])) { throw new Exception('Array key (name or level) missing from 3rd param of grade_edit_tree_column_name::get_category_cell($category, $levelclass, $params)'); } - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' name ' . $levelclass; + $moveaction = isset($params['moveaction']) ? $params['moveaction'] : ''; + $categorycell = parent::get_category_cell($category, $levelclass, $params); $categorycell->colspan = ($this->deepest_level +1) - $params['level']; - $categorycell->text = $OUTPUT->heading($params['name'], 4); + $categorycell->text = $OUTPUT->heading($moveaction . $params['name'], 4); return $categorycell; } @@ -629,20 +671,22 @@ class grade_edit_tree_column_name extends grade_edit_tree_column { } $name = $params['name']; + $moveaction = isset($params['moveaction']) ? $params['moveaction'] : ''; - $itemcell = clone($this->itemcell); - $itemcell->attributes['class'] .= ' name'; + $itemcell = parent::get_item_cell($item, $params); $itemcell->colspan = ($this->deepest_level + 1) - $params['level']; - $itemcell->text = $name; + $itemcell->text = $moveaction . $name; return $itemcell; } - - public function is_hidden($mode='simple') { - return false; - } } -class grade_edit_tree_column_aggregation extends grade_edit_tree_column_category { +/** + * Class grade_edit_tree_column_aggregation + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class grade_edit_tree_column_aggregation extends grade_edit_tree_column { public function __construct($params) { parent::__construct('aggregation'); @@ -661,106 +705,42 @@ class grade_edit_tree_column_aggregation extends grade_edit_tree_column_category throw new Exception('Array key (id) missing from 3rd param of grade_edit_tree_column_aggregation::get_category_cell($category, $levelclass, $params)'); } - $options = array(GRADE_AGGREGATE_MEAN => get_string('aggregatemean', 'grades'), - GRADE_AGGREGATE_WEIGHTED_MEAN => get_string('aggregateweightedmean', 'grades'), - GRADE_AGGREGATE_WEIGHTED_MEAN2 => get_string('aggregateweightedmean2', 'grades'), - GRADE_AGGREGATE_EXTRACREDIT_MEAN => get_string('aggregateextracreditmean', 'grades'), - GRADE_AGGREGATE_MEDIAN => get_string('aggregatemedian', 'grades'), - GRADE_AGGREGATE_MIN => get_string('aggregatemin', 'grades'), - GRADE_AGGREGATE_MAX => get_string('aggregatemax', 'grades'), - GRADE_AGGREGATE_MODE => get_string('aggregatemode', 'grades'), - GRADE_AGGREGATE_SUM => get_string('aggregatesum', 'grades')); + $options = grade_helper::get_aggregation_strings(); + $aggregation = $options[$category->aggregation]; - $visible = explode(',', $CFG->grade_aggregations_visible); - foreach ($options as $constant => $string) { - if (!in_array($constant, $visible) && $constant != $category->aggregation) { - unset($options[$constant]); - } - } - - if ($this->forced) { - $aggregation = $options[$category->aggregation]; - } else { - $attributes = array(); - $attributes['id'] = 'aggregation_'.$category->id; - $attributes['class'] = 'ignoredirty'; - $aggregation = html_writer::label(get_string('aggregation', 'grades'), 'aggregation_'.$category->id, false, array('class' => 'accesshide')); - $aggregation .= html_writer::select($options, 'aggregation_'.$category->id, $category->aggregation, null, $attributes); - $action = new component_action('change', 'update_category_aggregation', array('courseid' => $params['id'], 'category' => $category->id, 'sesskey' => sesskey())); - $OUTPUT->add_action_handler($action, 'aggregation_'.$category->id); - } - - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; + $categorycell = parent::get_category_cell($category, $levelclass, $params); $categorycell->text = $aggregation; return $categorycell; } public function get_item_cell($item, $params) { - $itemcell = clone($this->itemcell); + $itemcell = parent::get_item_cell($item, $params); $itemcell->text = ' - '; return $itemcell; } } -class grade_edit_tree_column_extracredit extends grade_edit_tree_column { - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->text = get_string('aggregationcoefextra', 'grades').$OUTPUT->help_icon('aggregationcoefextra', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $item = $category->get_grade_item(); - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = grade_edit_tree::get_weight_input($item, 'extra'); - return $categorycell; - } - - public function get_item_cell($item, $params) { - if (empty($params['element'])) { - throw new Exception('Array key (element) missing from 2nd param of grade_edit_tree_column_weightorextracredit::get_item_cell($item, $params)'); - } - - $itemcell = clone($this->itemcell); - $itemcell->text = ' '; - - if (!in_array($params['element']['object']->itemtype, array('courseitem', 'categoryitem', 'category'))) { - $itemcell->text = grade_edit_tree::get_weight_input($item, 'extra'); - } - - return $itemcell; - } - - public function is_hidden($mode='simple') { - global $CFG; - if ($mode == 'simple') { - return strstr($CFG->grade_item_advanced, 'aggregationcoef'); - } elseif ($mode == 'advanced') { - return false; - } - } -} - +/** + * Class grade_edit_tree_column_weight + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class grade_edit_tree_column_weight extends grade_edit_tree_column { public function get_header_cell() { global $OUTPUT; $headercell = clone($this->headercell); - $headercell->text = get_string('weightuc', 'grades').$OUTPUT->help_icon('aggregationcoefweight', 'grades'); + $headercell->text = get_string('weights', 'grades').$OUTPUT->help_icon('aggregationcoefweight', 'grades'); return $headercell; } public function get_category_cell($category, $levelclass, $params) { $item = $category->get_grade_item(); - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = grade_edit_tree::get_weight_input($item, 'weight'); + $categorycell = parent::get_category_cell($category, $levelclass, $params); + $categorycell->text = grade_edit_tree::get_weight_input($item); return $categorycell; } @@ -768,26 +748,23 @@ class grade_edit_tree_column_weight extends grade_edit_tree_column { if (empty($params['element'])) { throw new Exception('Array key (element) missing from 2nd param of grade_edit_tree_column_weightorextracredit::get_item_cell($item, $params)'); } - $itemcell = clone($this->itemcell); + $itemcell = parent::get_item_cell($item, $params); $itemcell->text = ' '; if (!in_array($params['element']['object']->itemtype, array('courseitem', 'categoryitem', 'category'))) { - $itemcell->text = grade_edit_tree::get_weight_input($item, 'weight'); + $itemcell->text = grade_edit_tree::get_weight_input($item); } return $itemcell; } - - public function is_hidden($mode='simple') { - global $CFG; - if ($mode == 'simple') { - return strstr($CFG->grade_item_advanced, 'aggregationcoef'); - } elseif ($mode == 'advanced') { - return false; - } - } } +/** + * Class grade_edit_tree_column_range + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class grade_edit_tree_column_range extends grade_edit_tree_column { public function get_header_cell() { @@ -797,8 +774,7 @@ class grade_edit_tree_column_range extends grade_edit_tree_column { } public function get_category_cell($category, $levelclass, $params) { - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' range ' . $levelclass; + $categorycell = parent::get_category_cell($category, $levelclass, $params); $categorycell->text = ' - '; return $categorycell; } @@ -806,14 +782,12 @@ class grade_edit_tree_column_range extends grade_edit_tree_column { public function get_item_cell($item, $params) { global $DB, $OUTPUT; - // If the parent aggregation is Sum of Grades, we should show the number, even for scales, as that value is used... + // If the parent aggregation is Natural, we should show the number, even for scales, as that value is used... // ...in the computation. For text grades, the grademax is not used, so we can still show the no value string. $parent_cat = $item->get_parent_category(); if ($item->gradetype == GRADE_TYPE_TEXT) { $grademax = ' - '; - } else if ($parent_cat->aggregation == GRADE_AGGREGATE_SUM) { - $grademax = format_float($item->grademax, $item->get_decimals()); - } elseif ($item->gradetype == GRADE_TYPE_SCALE) { + } else if ($item->gradetype == GRADE_TYPE_SCALE) { $scale = $DB->get_record('scale', array('id' => $item->scaleid)); $scale_items = null; if (empty($scale)) { //if the item is using a scale that's been removed @@ -821,323 +795,28 @@ class grade_edit_tree_column_range extends grade_edit_tree_column { } else { $scale_items = explode(',', $scale->scale); } - $grademax = end($scale_items) . ' (' . count($scale_items) . ')'; - } elseif ($item->is_external_item()) { - $grademax = format_float($item->grademax, $item->get_decimals()); + if ($parent_cat->aggregation == GRADE_AGGREGATE_SUM) { + $grademax = end($scale_items) . ' (' . + format_float($item->grademax, $item->get_decimals()) . ')'; + } else { + $grademax = end($scale_items) . ' (' . count($scale_items) . ')'; + } } else { - $grademax = ' - '; + $grademax = format_float($item->grademax, $item->get_decimals()); } - $itemcell = clone($this->itemcell); + $itemcell = parent::get_item_cell($item, $params); $itemcell->text = $grademax; return $itemcell; } - - public function is_hidden($mode='simple') { - global $CFG; - if ($mode == 'simple') { - return strstr($CFG->grade_item_advanced, 'grademax'); - } elseif ($mode == 'advanced') { - return false; - } - } -} - -class grade_edit_tree_column_aggregateonlygraded extends grade_edit_tree_column_category { - - public function __construct($params) { - parent::__construct('aggregateonlygraded'); - } - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->style .= 'width: 40px;'; - $headercell->text = get_string('aggregateonlygraded', 'grades') - . $OUTPUT->help_icon('aggregateonlygraded', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $onlygradedcheck = ($category->aggregateonlygraded == 1) ? 'checked="checked"' : ''; - $hidden = ''; - $aggregateonlygraded = ' - '; - - if ($this->forced) { - $aggregateonlygraded = ($category->aggregateonlygraded) ? get_string('yes') : get_string('no'); - } - - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = $hidden.$aggregateonlygraded; - return $categorycell; - } - - public function get_item_cell($item, $params) { - $itemcell = clone($this->itemcell); - $itemcell->text = ' - '; - return $itemcell; - } -} - -class grade_edit_tree_column_aggregatesubcats extends grade_edit_tree_column_category { - - public function __construct($params) { - parent::__construct('aggregatesubcats'); - } - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->style .= 'width: 40px;'; - $headercell->text = get_string('aggregatesubcats', 'grades') - .$OUTPUT->help_icon('aggregatesubcats', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $subcatscheck = ($category->aggregatesubcats == 1) ? 'checked="checked"' : ''; - $hidden = ''; - $aggregatesubcats = ' - '; - - if ($this->forced) { - $aggregatesubcats = ($category->aggregatesubcats) ? get_string('yes') : get_string('no'); - } - - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = $hidden.$aggregatesubcats; - return $categorycell; - - } - - public function get_item_cell($item, $params) { - $itemcell = clone($this->itemcell); - $itemcell->text = ' - '; - return $itemcell; - } -} - -class grade_edit_tree_column_aggregateoutcomes extends grade_edit_tree_column_category { - - public function __construct($params) { - parent::__construct('aggregateoutcomes'); - } - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->style .= 'width: 40px;'; - $headercell->text = get_string('aggregateoutcomes', 'grades') - .$OUTPUT->help_icon('aggregateoutcomes', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $outcomescheck = ($category->aggregateoutcomes == 1) ? 'checked="checked"' : ''; - $hidden = ''; - $aggregateoutcomes = ' - '; - - if ($this->forced) { - $aggregateoutcomes = ($category->aggregateoutcomes) ? get_string('yes') : get_string('no'); - } - - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = $hidden.$aggregateoutcomes; - return $categorycell; - } - - public function get_item_cell($item, $params) { - $itemcell = clone($this->itemcell); - $itemcell->text = ' - '; - return $itemcell; - } - - public function is_hidden($mode='simple') { - global $CFG; - if ($CFG->enableoutcomes) { - return parent::is_hidden($mode); - } else { - return true; - } - } -} - -class grade_edit_tree_column_droplow extends grade_edit_tree_column_category { - - public function __construct($params) { - parent::__construct('droplow'); - } - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->text = get_string('droplow', 'grades').$OUTPUT->help_icon('droplow', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $droplow = ''; - $droplow .= ''; - - if ($this->forced) { - $droplow = $category->droplow; - } - - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = $droplow; - return $categorycell; - } - - public function get_item_cell($item, $params) { - $itemcell = clone($this->itemcell); - $itemcell->text = ' - '; - return $itemcell; - } -} - -class grade_edit_tree_column_keephigh extends grade_edit_tree_column_category { - - public function __construct($params) { - parent::__construct('keephigh'); - } - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->text = get_string('keephigh', 'grades').$OUTPUT->help_icon('keephigh', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $keephigh = ''; - $keephigh .= ''; - - if ($this->forced) { - $keephigh = $category->keephigh; - } - - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = $keephigh; - return $categorycell; - } - - public function get_item_cell($item, $params) { - $itemcell = clone($this->itemcell); - $itemcell->text = ' - '; - return $itemcell; - } -} - -class grade_edit_tree_column_multfactor extends grade_edit_tree_column { - - public function __construct($params) { - parent::__construct(); - } - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->text = get_string('multfactor', 'grades').$OUTPUT->help_icon('multfactor', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = ' - '; - return $categorycell; - } - - public function get_item_cell($item, $params) { - global $OUTPUT; - - $itemcell = clone($this->itemcell); - if (!$item->is_raw_used()) { - $itemcell->text = ' '; - return $itemcell; - } - $multfactor = ' - '; - - $itemcell->text = $multfactor; - return $itemcell; - } - - public function is_hidden($mode='simple') { - global $CFG; - if ($mode == 'simple') { - return strstr($CFG->grade_item_advanced, 'multfactor'); - } elseif ($mode == 'advanced') { - return false; - } - } -} - -class grade_edit_tree_column_plusfactor extends grade_edit_tree_column { - - public function get_header_cell() { - global $OUTPUT; - $headercell = clone($this->headercell); - $headercell->text = get_string('plusfactor', 'grades').$OUTPUT->help_icon('plusfactor', 'grades'); - return $headercell; - } - - public function get_category_cell($category, $levelclass, $params) { - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; - $categorycell->text = ' - '; - return $categorycell; - - } - - public function get_item_cell($item, $params) { - global $OUTPUT; - - $itemcell = clone($this->itemcell); - if (!$item->is_raw_used()) { - $itemcell->text = ' '; - return $itemcell; - } - - $plusfactor = ' - '; - - $itemcell->text = $plusfactor; - return $itemcell; - - } - - public function is_hidden($mode='simple') { - global $CFG; - if ($mode == 'simple') { - return strstr($CFG->grade_item_advanced, 'plusfactor'); - } elseif ($mode == 'advanced') { - return false; - } - } } +/** + * Class grade_edit_tree_column_actions + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class grade_edit_tree_column_actions extends grade_edit_tree_column { public function __construct($params) { @@ -1146,7 +825,6 @@ class grade_edit_tree_column_actions extends grade_edit_tree_column { public function get_header_cell() { $headercell = clone($this->headercell); - $headercell->attributes['class'] .= ' actions'; $headercell->text = get_string('actions'); return $headercell; } @@ -1157,8 +835,7 @@ class grade_edit_tree_column_actions extends grade_edit_tree_column { throw new Exception('Array key (actions) missing from 3rd param of grade_edit_tree_column_actions::get_category_actions($category, $levelclass, $params)'); } - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' ' . $levelclass; + $categorycell = parent::get_category_cell($category, $levelclass, $params); $categorycell->text = $params['actions']; return $categorycell; } @@ -1167,22 +844,22 @@ class grade_edit_tree_column_actions extends grade_edit_tree_column { if (empty($params['actions'])) { throw new Exception('Array key (actions) missing from 2nd param of grade_edit_tree_column_actions::get_item_cell($item, $params)'); } - $itemcell = clone($this->itemcell); - $itemcell->attributes['class'] .= ' actions'; + $itemcell = parent::get_item_cell($item, $params); $itemcell->text = $params['actions']; return $itemcell; } - - public function is_hidden($mode='simple') { - return false; - } } +/** + * Class grade_edit_tree_column_select + * + * @package core_grades + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class grade_edit_tree_column_select extends grade_edit_tree_column { public function get_header_cell() { $headercell = clone($this->headercell); - $headercell->attributes['class'] .= ' selection'; $headercell->text = get_string('select'); return $headercell; } @@ -1195,9 +872,7 @@ class grade_edit_tree_column_select extends grade_edit_tree_column { $selectall = new action_link(new moodle_url('#'), get_string('all'), new component_action('click', 'togglecheckboxes', array('eid' => $params['eid'], 'check' => true))); $selectnone = new action_link(new moodle_url('#'), get_string('none'), new component_action('click', 'togglecheckboxes', array('eid' => $params['eid'], 'check' => false))); - $categorycell = clone($this->categorycell); - $categorycell->attributes['class'] .= ' last ' . $levelclass; - $categorycell->style .= 'text-align: center;'; + $categorycell = parent::get_category_cell($category, $levelclass, $params); $categorycell->text = $OUTPUT->render($selectall) . '
' . $OUTPUT->render($selectnone); return $categorycell; } @@ -1206,20 +881,15 @@ class grade_edit_tree_column_select extends grade_edit_tree_column { if (empty($params['itemtype']) || empty($params['eid'])) { error('Array key (itemtype or eid) missing from 2nd param of grade_edit_tree_column_select::get_item_cell($item, $params)'); } - $itemselect = ''; + $itemcell = parent::get_item_cell($item, $params); if ($params['itemtype'] != 'course' && $params['itemtype'] != 'category') { - $itemselect = '