Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * The Gradebook setup page. 19 * 20 * @package core_grades 21 * @copyright 2008 Nicolas Connault 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 define('NO_OUTPUT_BUFFERING', true); // The progress bar may be used here. 26 27 require_once '../../../config.php'; 28 require_once $CFG->dirroot.'/grade/lib.php'; 29 require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences 30 require_once $CFG->dirroot.'/grade/edit/tree/lib.php'; 31 32 $courseid = required_param('id', PARAM_INT); 33 $action = optional_param('action', 0, PARAM_ALPHA); 34 $eid = optional_param('eid', 0, PARAM_ALPHANUM); 35 $weightsadjusted = optional_param('weightsadjusted', 0, PARAM_INT); 36 37 $url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid)); 38 $PAGE->set_url($url); 39 $PAGE->set_pagelayout('admin'); 40 41 /// Make sure they can even access this course 42 if (!$course = $DB->get_record('course', array('id' => $courseid))) { 43 throw new \moodle_exception('invalidcourseid'); 44 } 45 46 require_login($course); 47 $context = context_course::instance($course->id); 48 require_capability('moodle/grade:manage', $context); 49 50 $PAGE->requires->js_call_amd('core_grades/edittree_index', 'init', [$courseid, $USER->id]); 51 $PAGE->requires->js_call_amd('core_grades/gradebooksetup_forms', 'init'); 52 53 $decsep = get_string('decsep', 'langconfig'); 54 // This setting indicates if we should use algorithm prior to MDL-49257 fix for calculating extra credit weights. 55 $gradebookcalculationfreeze = (int) get_config('core', 'gradebook_calculations_freeze_' . $courseid); 56 $oldextracreditcalculation = $gradebookcalculationfreeze && ($gradebookcalculationfreeze <= 20150619); 57 $PAGE->requires->js_call_amd('core_grades/edittree_weights', 'init', [$decsep, $oldextracreditcalculation]); 58 59 /// return tracking object 60 $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid)); 61 $returnurl = $gpr->get_return_url(null); 62 63 // get the grading tree object 64 // note: total must be first for moving to work correctly, if you want it last moving code must be rewritten! 65 $gtree = new grade_tree($courseid, false, false); 66 67 if (empty($eid)) { 68 $element = null; 69 $object = null; 70 71 } else { 72 if (!$element = $gtree->locate_element($eid)) { 73 throw new \moodle_exception('invalidelementid', '', $returnurl); 74 } 75 $object = $element['object']; 76 } 77 78 $switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggregationposition); 79 80 $strgrades = get_string('grades'); 81 $strgraderreport = get_string('graderreport', 'grades'); 82 83 $moving = false; 84 $movingeid = false; 85 86 if ($action == 'moveselect') { 87 if ($eid and confirm_sesskey()) { 88 $movingeid = $eid; 89 $moving=true; 90 } 91 } 92 93 $gradeedittree = new grade_edit_tree($gtree, $movingeid, $gpr); 94 95 switch ($action) { 96 case 'duplicate': 97 if ($eid and confirm_sesskey()) { 98 if (!$el = $gtree->locate_element($eid)) { 99 throw new \moodle_exception('invalidelementid', '', $returnurl); 100 } 101 102 $object->duplicate(); 103 redirect($returnurl); 104 } 105 break; 106 107 case 'delete': 108 if ($eid && confirm_sesskey()) { 109 if (!$gradeedittree->element_deletable($element)) { 110 // no deleting of external activities - they would be recreated anyway! 111 // exception is activity without grading or misconfigured activities 112 break; 113 } 114 $confirm = optional_param('confirm', 0, PARAM_BOOL); 115 116 if ($confirm) { 117 $object->delete('grade/report/grader/category'); 118 redirect($returnurl); 119 120 } 121 } 122 break; 123 124 case 'autosort': 125 //TODO: implement autosorting based on order of mods on course page, categories first, manual items last 126 break; 127 128 case 'move': 129 if ($eid and confirm_sesskey()) { 130 $moveafter = required_param('moveafter', PARAM_ALPHANUM); 131 $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 132 133 if(!$after_el = $gtree->locate_element($moveafter)) { 134 throw new \moodle_exception('invalidelementid', '', $returnurl); 135 } 136 137 $after = $after_el['object']; 138 $sortorder = $after->get_sortorder(); 139 140 if (!$first) { 141 $parent = $after->get_parent_category(); 142 $object->set_parent($parent->id); 143 } else { 144 $object->set_parent($after->id); 145 } 146 147 $object->move_after_sortorder($sortorder); 148 149 redirect($returnurl); 150 } 151 break; 152 153 default: 154 break; 155 } 156 157 // If we go straight to the db to update an element we need to recreate the tree as 158 // $gradeedittree has already been constructed. 159 // Ideally we could do the updates through $gradeedittree to avoid recreating it. 160 $recreatetree = false; 161 162 if ($data = data_submitted() and confirm_sesskey()) { 163 // Perform bulk actions first 164 if (!empty($data->bulkmove)) { 165 $elements = array(); 166 167 foreach ($data as $key => $value) { 168 if (preg_match('/select_(ig[0-9]*)/', $key, $matches)) { 169 $elements[] = $matches[1]; 170 } 171 } 172 173 $gradeedittree->move_elements($elements, $returnurl); 174 } 175 176 // Update weights (extra credits) on categories and items. 177 foreach ($data as $key => $value) { 178 if (preg_match('/^weight_([0-9]+)$/', $key, $matches)) { 179 $aid = $matches[1]; 180 181 $value = unformat_float($value); 182 $value = clean_param($value, PARAM_FLOAT); 183 184 $grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid)); 185 186 // Convert weight to aggregation coef2. 187 $aggcoef = $grade_item->get_coefstring(); 188 if ($aggcoef == 'aggregationcoefextraweightsum') { 189 // The field 'weight' should only be sent when the checkbox 'weighoverride' is checked, 190 // so there is not need to set weightoverride here, it is done below. 191 $value = $value / 100.0; 192 $grade_item->aggregationcoef2 = $value; 193 } else if ($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoefextraweight') { 194 $grade_item->aggregationcoef = $value; 195 } 196 197 $grade_item->update(); 198 199 $recreatetree = true; 200 201 // Grade item checkbox inputs. 202 } elseif (preg_match('/^(weightoverride)_([0-9]+)$/', $key, $matches)) { 203 $param = $matches[1]; 204 $aid = $matches[2]; 205 $value = clean_param($value, PARAM_BOOL); 206 207 $grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid)); 208 $grade_item->$param = $value; 209 210 $grade_item->update(); 211 212 $recreatetree = true; 213 } 214 } 215 } 216 217 $originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid); 218 219 /** 220 * Callback function to adjust the URL if weights changed after the 221 * regrade. 222 * 223 * @param int $courseid The course ID 224 * @param array $originalweights The weights before the regrade 225 * @param int $weightsadjusted Whether weights have been adjusted 226 * @return moodle_url A URL to redirect to after regrading when a progress bar is displayed. 227 */ 228 $grade_edit_tree_index_checkweights = function() use ($courseid, $originalweights, &$weightsadjusted) { 229 global $PAGE; 230 231 $alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid); 232 if (array_diff($originalweights, $alteredweights)) { 233 $weightsadjusted = 1; 234 return new moodle_url($PAGE->url, array('weightsadjusted' => $weightsadjusted)); 235 } 236 return $PAGE->url; 237 }; 238 239 if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_checkweights)) { 240 $recreatetree = true; 241 } 242 243 $actionbar = new \core_grades\output\gradebook_setup_action_bar($context); 244 print_grade_page_head($courseid, 'settings', 'setup', false, 245 false, false, true, null, null, null, $actionbar); 246 247 // Print Table of categories and items 248 echo $OUTPUT->box_start('gradetreebox generalbox'); 249 250 // Did we update something in the db and thus invalidate $gradeedittree? 251 if ($recreatetree) { 252 $gradeedittree = new grade_edit_tree($gtree, $movingeid, $gpr); 253 } 254 255 $tpldata = (object) [ 256 'actionurl' => $returnurl, 257 'sesskey' => sesskey(), 258 'movingmodeenabled' => $moving, 259 'courseid' => $courseid 260 ]; 261 262 // Check to see if we have a normalisation message to send. 263 if ($weightsadjusted) { 264 $notification = new \core\output\notification(get_string('weightsadjusted', 'grades'), \core\output\notification::NOTIFY_INFO); 265 $tpldata->notification = $notification->export_for_template($OUTPUT); 266 } 267 268 $tpldata->table = html_writer::table($gradeedittree->table); 269 270 // If not in moving mode and there is more than one grade category, then initialise the bulk action module. 271 if (!$moving && count($gradeedittree->categories) > 1) { 272 $PAGE->requires->js_call_amd('core_grades/bulkactions/edit/tree/bulk_actions', 'init', [$courseid]); 273 } 274 275 $footercontent = $OUTPUT->render_from_template('core_grades/edit_tree_sticky_footer', $tpldata); 276 $stickyfooter = new core\output\sticky_footer($footercontent); 277 $tpldata->stickyfooter = $OUTPUT->render($stickyfooter); 278 279 echo $OUTPUT->render_from_template('core_grades/edit_tree', $tpldata); 280 281 echo $OUTPUT->box_end(); 282 283 $PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['gradetreeform']); 284 285 echo $OUTPUT->footer(); 286 die;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body