MDL-44859 grade: Inverse the order of the add category and item buttons
[moodle.git] / grade / edit / tree / index.php
CommitLineData
e060e33d 1<?php
e060e33d 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/>.
f13002d5 16
1c1f64a2 17/**
53914e44 18 * The Gradebook setup page.
1c1f64a2 19 *
a153c9f2 20 * @package core_grades
1c1f64a2 21 * @copyright 2008 Nicolas Connault
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
78ad5f3f 25require_once '../../../config.php';
3af29899 26require_once $CFG->dirroot.'/grade/lib.php';
eedd3aa2 27require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences
dc482cfa 28require_once $CFG->dirroot.'/grade/edit/tree/lib.php';
f13002d5 29
dc482cfa 30$courseid = required_param('id', PARAM_INT);
31$action = optional_param('action', 0, PARAM_ALPHA);
32$eid = optional_param('eid', 0, PARAM_ALPHANUM);
87d71ecf 33$weightsadjusted = optional_param('weightsadjusted', 0, PARAM_INT);
5bfa0d79 34
160fe5ff 35$url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid));
160fe5ff 36$PAGE->set_url($url);
4d5059d4 37$PAGE->set_pagelayout('admin');
1c1f64a2 38
b78bb4f7 39/// Make sure they can even access this course
aaf54d21 40if (!$course = $DB->get_record('course', array('id' => $courseid))) {
d9ce6a4f 41 print_error('invalidcourseid');
b78bb4f7 42}
43
f13002d5 44require_login($course);
d4060472 45$context = context_course::instance($course->id);
7a6b7acf 46require_capability('moodle/grade:manage', $context);
47
a066cfc8 48$PAGE->requires->js_call_amd('core_grades/edittree_index', 'enhance');
d1ae61fe 49
7a6b7acf 50/// return tracking object
78ad5f3f 51$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
7a6b7acf 52$returnurl = $gpr->get_return_url(null);
b78bb4f7 53
f13002d5 54// get the grading tree object
d3f14e42 55// note: total must be first for moving to work correctly, if you want it last moving code must be rewritten!
938e00b6 56$gtree = new grade_tree($courseid, false, false);
210611f6 57
f13002d5 58if (empty($eid)) {
59 $element = null;
60 $object = null;
5bfa0d79 61
f13002d5 62} else {
63 if (!$element = $gtree->locate_element($eid)) {
1bb0aa0f 64 print_error('invalidelementid', '', $returnurl);
f13002d5 65 }
7a6b7acf 66 $object = $element['object'];
f13002d5 67}
b3ac6c3e 68
e0724506 69$switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggregationposition);
b3ac6c3e 70
826c5f86 71$strgrades = get_string('grades');
72$strgraderreport = get_string('graderreport', 'grades');
b3ac6c3e 73
f13002d5 74$moving = false;
54a007e8 75$movingeid = false;
f13002d5 76
54a007e8 77if ($action == 'moveselect') {
78 if ($eid and confirm_sesskey()) {
79 $movingeid = $eid;
80 $moving=true;
81 }
82}
83
84$grade_edit_tree = new grade_edit_tree($gtree, $movingeid, $gpr);
dc482cfa 85
f13002d5 86switch ($action) {
f13002d5 87 case 'delete':
653a8648 88 if ($eid && confirm_sesskey()) {
dc482cfa 89 if (!$grade_edit_tree->element_deletable($element)) {
23160003 90 // no deleting of external activities - they would be recreated anyway!
796a41b5 91 // exception is activity without grading or misconfigured activities
61a5ee16 92 break;
93 }
f943f4fd 94 $confirm = optional_param('confirm', 0, PARAM_BOOL);
95
cd3a391c 96 if ($confirm) {
f943f4fd 97 $object->delete('grade/report/grader/category');
98 redirect($returnurl);
99
100 } else {
7cc378fd 101 $PAGE->set_title($strgrades . ': ' . $strgraderreport);
02114f13 102 $PAGE->set_heading($course->fullname);
7cc378fd 103 echo $OUTPUT->header();
f943f4fd 104 $strdeletecheckfull = get_string('deletecheck', '', $object->get_name());
105 $optionsyes = array('eid'=>$eid, 'confirm'=>1, 'sesskey'=>sesskey(), 'id'=>$course->id, 'action'=>'delete');
106 $optionsno = array('id'=>$course->id);
dc6896ef 107 $formcontinue = new single_button(new moodle_url('index.php', $optionsyes), get_string('yes'));
3ba60ee1 108 $formcancel = new single_button(new moodle_url('index.php', $optionsno), get_string('no'), 'get');
03fcc729 109 echo $OUTPUT->confirm($strdeletecheckfull, $formcontinue, $formcancel);
5a931394 110 echo $OUTPUT->footer();
f943f4fd 111 die;
112 }
113 }
f13002d5 114 break;
115
739196ba 116 case 'autosort':
117 //TODO: implement autosorting based on order of mods on course page, categories first, manual items last
118 break;
119
f13002d5 120 case 'move':
121 if ($eid and confirm_sesskey()) {
122 $moveafter = required_param('moveafter', PARAM_ALPHANUM);
dc482cfa 123 $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
124
f13002d5 125 if(!$after_el = $gtree->locate_element($moveafter)) {
1bb0aa0f 126 print_error('invalidelementid', '', $returnurl);
f13002d5 127 }
dc482cfa 128
f13002d5 129 $after = $after_el['object'];
f13002d5 130 $sortorder = $after->get_sortorder();
131
dc482cfa 132 if (!$first) {
133 $parent = $after->get_parent_category();
134 $object->set_parent($parent->id);
135 } else {
136 $object->set_parent($after->id);
137 }
138
f13002d5 139 $object->move_after_sortorder($sortorder);
140
141 redirect($returnurl);
142 }
143 break;
144
f13002d5 145 default:
146 break;
b3ac6c3e 147}
b3ac6c3e 148
5e212c33
AD
149//if we go straight to the db to update an element we need to recreate the tree as
150// $grade_edit_tree has already been constructed.
151//Ideally we could do the updates through $grade_edit_tree to avoid recreating it
152$recreatetree = false;
153
cd3a391c 154if ($data = data_submitted() and confirm_sesskey()) {
dc482cfa 155 // Perform bulk actions first
cd3a391c 156 if (!empty($data->bulkmove)) {
dc482cfa 157 $elements = array();
f13002d5 158
dc482cfa 159 foreach ($data as $key => $value) {
ddb9c95f 160 if (preg_match('/select_(ig[0-9]*)/', $key, $matches)) {
dc482cfa 161 $elements[] = $matches[1];
162 }
163 }
6cc3e350 164
dc482cfa 165 $grade_edit_tree->move_elements($elements, $returnurl);
6cc3e350 166 }
167
b79bf7a2 168 // Update weights (extra credits) on categories and items.
dc482cfa 169 foreach ($data as $key => $value) {
b79bf7a2
MG
170 if (preg_match('/^weight_([0-9]+)$/', $key, $matches)) {
171 $aid = $matches[1];
126d92d3 172
cd3a391c 173 $value = unformat_float($value);
61cca0b7 174 $value = clean_param($value, PARAM_FLOAT);
126d92d3 175
32ee0f83 176 $grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
cd3a391c 177
b6a1e366 178 // Convert weight to aggregation coef2.
b79bf7a2
MG
179 $aggcoef = $grade_item->get_coefstring();
180 if ($aggcoef == 'aggregationcoefextraweightsum') {
6c37563e
FM
181 // The field 'weight' should only be sent when the checkbox 'weighoverride' is checked,
182 // so there is not need to set weightoverride here, it is done below.
b79bf7a2 183 $value = $value / 100.0;
b79bf7a2
MG
184 $grade_item->aggregationcoef2 = $value;
185 } else if ($aggcoef == 'aggregationcoefweight' || $aggcoef == 'aggregationcoefextraweight') {
186 $grade_item->aggregationcoef = $value;
45da5361 187 }
f13002d5 188
8ad3ee9c 189 $grade_item->update();
f13002d5 190
6c37563e
FM
191 $recreatetree = true;
192
193 // Grade item checkbox inputs.
194 } elseif (preg_match('/^(weightoverride)_([0-9]+)$/', $key, $matches)) {
195 $param = $matches[1];
196 $aid = $matches[2];
197 $value = clean_param($value, PARAM_BOOL);
198
199 $grade_item = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
200 $grade_item->$param = $value;
201
202 $grade_item->update();
203
5e212c33 204 $recreatetree = true;
f13002d5 205 }
206 }
87d71ecf 207}
32ee0f83 208
87d71ecf
AN
209$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
210
211/**
212 * Callback function to adjust the URL if weights changed after the
213 * regrade.
214 *
215 * @param int $courseid The course ID
216 * @param array $originalweights The weights before the regrade
217 * @param int $weightsadjusted Whether weights have been adjusted
218 * @return moodle_url A URL to redirect to after regrading when a progress bar is displayed.
219 */
220$grade_edit_tree_index_checkweights = function() use ($courseid, $originalweights, &$weightsadjusted) {
221 global $PAGE;
e61f25a4 222
e61f25a4
DW
223 $alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
224 if (array_diff($originalweights, $alteredweights)) {
87d71ecf
AN
225 $weightsadjusted = 1;
226 return new moodle_url($PAGE->url, array('weightsadjusted' => $weightsadjusted));
519429b2 227 }
87d71ecf
AN
228 return $PAGE->url;
229};
f13002d5 230
87d71ecf 231if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_checkweights)) {
0a802c9c 232 $recreatetree = true;
30be6c84
DW
233}
234
53914e44 235print_grade_page_head($courseid, 'settings', 'setup', get_string('gradebooksetup', 'grades'));
76ea4e1f 236
dc482cfa 237// Print Table of categories and items
291fa827 238echo $OUTPUT->box_start('gradetreebox generalbox');
796a41b5 239
5e212c33
AD
240//did we update something in the db and thus invalidate $grade_edit_tree?
241if ($recreatetree) {
242 $grade_edit_tree = new grade_edit_tree($gtree, $movingeid, $gpr);
243}
87d71ecf 244
d68a9ece
FM
245$bulkmoveoptions = ['' => get_string('choosedots')] + $grade_edit_tree->categories;
246$tpldata = (object) [
247 'actionurl' => $returnurl,
248 'sesskey' => sesskey(),
249 'showsave' => !$moving,
250 'showbulkmove' => !$moving && count($grade_edit_tree->categories) > 1,
251 'bulkmoveoptions' => array_map(function($option) use ($bulkmoveoptions) {
252 return [
253 'name' => $bulkmoveoptions[$option],
254 'value' => $option
255 ];
256 }, array_keys($bulkmoveoptions))
257];
258
519429b2 259// Check to see if we have a normalisation message to send.
87d71ecf 260if ($weightsadjusted) {
d68a9ece
FM
261 $notification = new \core\output\notification(get_string('weightsadjusted', 'grades'), \core\output\notification::NOTIFY_INFO);
262 $tpldata->notification = $notification->export_for_template($OUTPUT);
dc482cfa 263}
264
d68a9ece 265$tpldata->table = html_writer::table($grade_edit_tree->table);
796a41b5 266
d68a9ece 267echo $OUTPUT->render_from_template('core_grades/edit_tree', $tpldata);
dc482cfa 268
291fa827 269echo $OUTPUT->box_end();
dc482cfa 270
271// Print action buttons
90723839 272echo $OUTPUT->container_start('buttons mdl-align');
dc482cfa 273
274if ($moving) {
5c2ed7e2 275 echo $OUTPUT->single_button(new moodle_url('index.php', array('id'=>$course->id)), get_string('cancel'), 'get');
dc482cfa 276} else {
df24fb71
LB
277 echo $OUTPUT->single_button(new moodle_url('item.php', array('courseid' => $course->id)), get_string('additem',
278 'grades'), 'get');
dc482cfa 279 if (!empty($CFG->enableoutcomes)) {
5c2ed7e2 280 echo $OUTPUT->single_button(new moodle_url('outcomeitem.php', array('courseid'=>$course->id)), get_string('addoutcomeitem', 'grades'), 'get');
796a41b5 281 }
df24fb71
LB
282 echo $OUTPUT->single_button(new moodle_url('category.php', array('courseid' => $course->id)), get_string('addcategory',
283 'grades'), 'get');
5c2ed7e2 284 //echo $OUTPUT->(new moodle_url('index.php', array('id'=>$course->id, 'action'=>'autosort')), get_string('autosort', 'grades'), 'get');
796a41b5 285}
f13002d5 286
03fcc729 287echo $OUTPUT->container_end();
dc482cfa 288
742d9165
MN
289$PAGE->requires->yui_module('moodle-core-formchangechecker',
290 'M.core_formchangechecker.init',
291 array(array(
292 'formid' => 'gradetreeform'
293 ))
294);
295$PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle');
296
5a931394 297echo $OUTPUT->footer();
dc482cfa 298die;
299
6c3ef410 300