MDL-49324 grade: Ensure weights adjusted message is displayed

The grade settings page displays a message to inform users that weights
have been adjusted if they did not previously add up to the required 100%.

With the change to sometimes displaying a progress bar, whether the message
is displayed must be calculated immediately after the regrade took place,
and before the page redirects.

I have added a callback with arguments to the regrade_if_required function
which is called immediately after regrade has taken place (regardless of
whether the progress bar is required).

This callback modifies the PAGE URL such that the redirect message will be
displayed after the redirect. This does not use the session as the message
should only be displayed immediately after a change. If the user does not
click on the continue button after the progress bar has been displayed, and
comes back to the page later, this may be confusing.
This commit is contained in:
Andrew Nicols 2016-02-01 09:05:05 +08:00
parent 417c7f3b86
commit 87d71ecf69
2 changed files with 46 additions and 22 deletions

View File

@ -30,6 +30,7 @@ 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);
@ -51,17 +52,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);
//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);
$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);
@ -215,16 +205,31 @@ if ($data = data_submitted() and confirm_sesskey()) {
$recreatetree = true;
}
}
}
$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
$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)) {
$normalisationmessage = get_string('weightsadjusted', 'grades');
$weightsadjusted = 1;
return new moodle_url($PAGE->url, array('weightsadjusted' => $weightsadjusted));
}
}
return $PAGE->url;
};
if (grade_regrade_final_grades_if_required($course)) {
if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_checkweights)) {
$recreatetree = true;
}
@ -241,9 +246,10 @@ echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
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');
if ($weightsadjusted) {
echo $OUTPUT->notification(get_string('weightsadjusted', 'grades'), 'notifymessage');
}
echo html_writer::table($grade_edit_tree->table);

View File

@ -348,7 +348,7 @@ function grade_needs_regrade_progress_bar($courseid) {
$grade_items = grade_item::fetch_all(array('courseid' => $courseid));
list($sql, $params) = $DB->get_in_or_equal(array_keys($grade_items), SQL_PARAMS_NAMED, 'gi');
$gradecount = $DB->count_records_select('grade_grades', 'id ' . $sql, $params);
$gradecount = $DB->count_records_select('grade_grades', 'itemid ' . $sql, $params);
// This figure may seem arbitrary, but after analysis it seems that 100 grade_grades can be calculated in ~= 0.5 seconds.
// Any longer than this and we want to show the progress bar.
@ -363,10 +363,14 @@ function grade_needs_regrade_progress_bar($courseid) {
* completes. Otherwise the regrading will happen immediately and the page will be loaded as per
* normal.
*
* A callback may be specified, which is called if regrading has taken place.
* The callback may optionally return a URL which will be redirected to when the progress bar is present.
*
* @param stdClass $course The course to regrade
* @return bool Whether the regrade process has taken place
* @param callable $callback A function to call if regrading took place
* @return moodle_url The URL to redirect to if redirecting
*/
function grade_regrade_final_grades_if_required($course) {
function grade_regrade_final_grades_if_required($course, callable $callback = null) {
global $PAGE, $OUTPUT;
if (!grade_needs_regrade_final_grades($course->id)) {
@ -379,11 +383,25 @@ function grade_regrade_final_grades_if_required($course) {
echo $OUTPUT->heading(get_string('recalculatinggrades', 'grades'));
$progress = new \core\progress\display(true);
grade_regrade_final_grades($course->id, null, null, $progress);
echo $OUTPUT->continue_button($PAGE->url);
if ($callback) {
//
$url = call_user_func($callback);
}
if (empty($url)) {
$url = $PAGE->url;
}
echo $OUTPUT->continue_button($url);
echo $OUTPUT->footer();
die();
} else {
return grade_regrade_final_grades($course->id);
$result = grade_regrade_final_grades($course->id);
if ($callback) {
call_user_func($callback);
}
return $result;
}
}