diff --git a/grade/edit/tree/index.php b/grade/edit/tree/index.php
index 672888acb1e..49ab967ecac 100644
--- a/grade/edit/tree/index.php
+++ b/grade/edit/tree/index.php
@@ -30,8 +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);
-$category = optional_param('category', null, PARAM_INT);
-$aggregationtype = optional_param('aggregationtype', null, PARAM_INT);
+$weightsadjusted = optional_param('weightsadjusted', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid));
$PAGE->set_url($url);
@@ -53,33 +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);
-// 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))) {
- print_error('invalidcategoryid');
- }
-
- $data = new stdClass();
- $data->aggregation = $aggregationtype;
- grade_category::set_properties($grade_category, $data);
- $grade_category->update();
-
- grade_regrade_final_grades($courseid);
-}
-
-//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);
@@ -233,15 +205,32 @@ 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);
- grade_regrade_final_grades($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, $grade_edit_tree_index_checkweights)) {
+ $recreatetree = true;
}
print_grade_page_head($courseid, 'settings', 'setup', get_string('gradebooksetup', 'grades'));
@@ -257,9 +246,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');
+if ($weightsadjusted) {
+ echo $OUTPUT->notification(get_string('weightsadjusted', 'grades'), 'notifymessage');
}
echo html_writer::table($grade_edit_tree->table);
diff --git a/grade/export/lib.php b/grade/export/lib.php
index bf7b981819a..755fa8ad80d 100644
--- a/grade/export/lib.php
+++ b/grade/export/lib.php
@@ -699,8 +699,7 @@ class grade_export_update_buffer {
* @param $courseid int The course being exported
*/
function export_verify_grades($courseid) {
- $regraderesult = grade_regrade_final_grades($courseid);
- if (is_array($regraderesult)) {
- throw new moodle_exception('gradecantregrade', 'error', '', implode(', ', array_unique($regraderesult)));
+ if (grade_needs_regrade_final_grades($courseid)) {
+ throw new moodle_exception('gradesneedregrading', 'grades');
}
}
diff --git a/grade/lib.php b/grade/lib.php
index 52c296d4d83..66cf003698b 100644
--- a/grade/lib.php
+++ b/grade/lib.php
@@ -1002,6 +1002,11 @@ function print_grade_page_head($courseid, $active_type, $active_plugin=null,
grade_extend_settings($plugin_info, $courseid);
}
+ // Set the current report as active in the breadcrumbs.
+ if ($active_plugin !== null && $reportnav = $PAGE->settingsnav->find($active_plugin, navigation_node::TYPE_SETTING)) {
+ $reportnav->make_active();
+ }
+
$returnval = $OUTPUT->header();
if (!$return) {
diff --git a/grade/report/grader/index.php b/grade/report/grader/index.php
index f15efe25979..7885fdc90d8 100644
--- a/grade/report/grader/index.php
+++ b/grade/report/grader/index.php
@@ -115,9 +115,6 @@ if (!is_null($toggle) && !empty($toggle_type)) {
set_user_preferences(array('grade_report_show'.$toggle_type => $toggle));
}
-//first make sure we have proper final grades - this must be done before constructing of the grade tree
-grade_regrade_final_grades($courseid);
-
// Perform actions
if (!empty($target) && !empty($action) && confirm_sesskey()) {
grade_report_grader::do_process_action($target, $action, $courseid);
@@ -125,6 +122,9 @@ if (!empty($target) && !empty($action) && confirm_sesskey()) {
$reportname = get_string('pluginname', 'gradereport_grader');
+// Do this check just before printing the grade header (and only do it once).
+grade_regrade_final_grades_if_required($course);
+
// Print header
print_grade_page_head($COURSE->id, 'report', 'grader', $reportname, false, $buttons);
diff --git a/grade/report/outcomes/index.php b/grade/report/outcomes/index.php
index cc809abd889..092373ade80 100644
--- a/grade/report/outcomes/index.php
+++ b/grade/report/outcomes/index.php
@@ -40,7 +40,7 @@ $context = context_course::instance($course->id);
require_capability('gradereport/outcomes:view', $context);
// First make sure we have proper final grades.
-grade_regrade_final_grades($courseid);
+grade_regrade_final_grades_if_required($course);
// Grab all outcomes used in course.
$report_info = array();
diff --git a/grade/report/overview/index.php b/grade/report/overview/index.php
index e46885cb065..14eef55bc6b 100644
--- a/grade/report/overview/index.php
+++ b/grade/report/overview/index.php
@@ -107,8 +107,8 @@ if (!isset($USER->grade_last_report)) {
}
$USER->grade_last_report[$course->id] = 'overview';
-//first make sure we have proper final grades - this must be done before constructing of the grade tree
-grade_regrade_final_grades($courseid);
+// First make sure we have proper final grades.
+grade_regrade_final_grades_if_required($course);
if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
// Please note this would be extremely slow if we wanted to implement this properly for all teachers.
diff --git a/grade/report/singleview/index.php b/grade/report/singleview/index.php
index be9461ba13b..9d6ab824d3e 100644
--- a/grade/report/singleview/index.php
+++ b/grade/report/singleview/index.php
@@ -46,7 +46,16 @@ if (empty($itemid)) {
}
$courseparams = array('id' => $courseid);
-$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $courseparams));
+$pageparams = array(
+ 'id' => $courseid,
+ 'group' => $groupid,
+ 'userid' => $userid,
+ 'itemid' => $itemid,
+ 'item' => $itemtype,
+ 'page' => $page,
+ 'perpage' => $perpage,
+ );
+$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $pageparams));
$PAGE->set_pagelayout('incourse');
if (!$course = $DB->get_record('course', $courseparams)) {
@@ -78,9 +87,8 @@ if (!isset($USER->grade_last_report)) {
}
$USER->grade_last_report[$course->id] = 'singleview';
-// First make sure we have proper final grades -
-// this must be done before constructing of the grade tree.
-grade_regrade_final_grades($courseid);
+// First make sure we have proper final grades.
+grade_regrade_final_grades_if_required($course);
$report = new gradereport_singleview($courseid, $gpr, $context, $itemtype, $itemid);
diff --git a/grade/report/singleview/tests/behat/bulk_insert_grades.feature b/grade/report/singleview/tests/behat/bulk_insert_grades.feature
index a06a1821819..218a8320295 100644
--- a/grade/report/singleview/tests/behat/bulk_insert_grades.feature
+++ b/grade/report/singleview/tests/behat/bulk_insert_grades.feature
@@ -29,7 +29,6 @@ Feature: We can bulk insert grades for students in a course
| assign | C1 | a3 | Test assignment three | Submit something! |
| assign | C1 | a4 | Test assignment four | Submit nothing! |
- @javascript
Scenario: I can bulk insert grades and check their override flags for grade view.
Given I log in as "teacher1"
And I follow "Course 1"
@@ -44,7 +43,7 @@ Feature: We can bulk insert grades for students in a course
And I follow "Single view for Test assignment one"
Then the field "Grade for james (Student) 1" matches value "50.00"
And the field "Override for james (Student) 1" matches value "0"
- And I click on "Perform bulk insert" "checkbox"
+ And I set the field "Perform bulk insert" to "1"
And I set the field "Insert value" to "1.0"
And I press "Save"
And I press "Continue"
@@ -56,8 +55,8 @@ Feature: We can bulk insert grades for students in a course
And the field "Override for anna (Student) 3" matches value "1"
And the field "Grade for zac (Student) 4" matches value "1.00"
And the field "Override for zac (Student) 4" matches value "1"
- And I click on "All grades" "option"
- And I click on "Perform bulk insert" "checkbox"
+ And I set the field "For" to "All grades"
+ And I set the field "Perform bulk insert" to "1"
And I set the field "Insert value" to "2.0"
And I press "Save"
And I press "Continue"
@@ -70,7 +69,6 @@ Feature: We can bulk insert grades for students in a course
And the field "Grade for zac (Student) 4" matches value "2.00"
And the field "Override for zac (Student) 4" matches value "1"
- @javascript
Scenario: I can bulk insert grades and check their override flags for user view.
Given I log in as "teacher1"
And I follow "Course 1"
@@ -83,11 +81,11 @@ Feature: We can bulk insert grades for students in a course
And I press "Continue"
And I follow "View gradebook"
And I follow "Single view for Test assignment two"
- And I click on "Student 1" "option"
+ And I select "Student 1" from the "Select user..." singleselect
Then the field "Grade for Test assignment two" matches value "50.00"
And the field "Override for Test assignment two" matches value "0"
- And I click on "Perform bulk insert" "checkbox"
- And I click on "Empty grades" "option"
+ And I set the field "For" to "Empty grades"
+ And I set the field "Perform bulk insert" to "1"
And I set the field "Insert value" to "1.0"
And I press "Save"
And I press "Continue"
diff --git a/grade/report/singleview/tests/behat/singleview.feature b/grade/report/singleview/tests/behat/singleview.feature
index 8036568a660..f12404d80ec 100644
--- a/grade/report/singleview/tests/behat/singleview.feature
+++ b/grade/report/singleview/tests/behat/singleview.feature
@@ -50,13 +50,13 @@ Feature: We can use Single view
@javascript
Scenario: I can update grades, add feedback and exclude grades.
- Given I click on "Single view" "option"
- And I click on "Student 4" "option"
- And I click on "Override for Test assignment one" "checkbox"
+ Given I select "Single view" from the "Grade report" singleselect
+ And I select "Student 4" from the "Select user..." singleselect
+ And I set the field "Override for Test assignment one" to "1"
When I set the following fields to these values:
| Grade for Test assignment one | 10.00 |
| Feedback for Test assignment one | test data |
- And I click on "Exclude for Test assignment four" "checkbox"
+ And I set the field "Exclude for Test assignment four" to "1"
And I press "Save"
Then I should see "Grades were set for 2 items"
And I press "Continue"
@@ -74,14 +74,13 @@ Feature: We can use Single view
And I set the following fields to these values:
| Grade for james (Student) 1 | 12.05 |
| Feedback for james (Student) 1 | test data2 |
- And I click on "Exclude for holly (Student) 2" "checkbox"
+ And I set the field "Exclude for holly (Student) 2" to "1"
And I press "Save"
Then I should see "Grades were set for 2 items"
And I press "Continue"
And the field "Grade for james (Student) 1" matches value "12.05"
And the field "Exclude for holly (Student) 2" matches value "1"
- And I click on "Single view" "link"
- And I click on "new grade item 1" "option"
+ And I select "new grade item 1" from the "Select grade item..." singleselect
And I click on "Very good" "option"
And I press "Save"
Then I should see "Grades were set for 1 items"
@@ -97,13 +96,12 @@ Feature: We can use Single view
And I follow "Single view for Student 1"
Then I should see "Student 1"
- @javascript
Scenario: I can bulk update grades.
Given I follow "Single view for Student 1"
Then I should see "Student 1"
- When I click on "All grades" "option"
+ When I set the field "For" to "All grades"
And I set the field "Insert value" to "1.0"
- And I click on "Perform bulk insert" "checkbox"
+ And I set the field "Perform bulk insert" to "1"
And I press "Save"
Then I should see "Grades were set for 8 items"
diff --git a/grade/report/singleview/tests/screen_test.php b/grade/report/singleview/tests/screen_test.php
index 2476d08a04f..eed99219f38 100644
--- a/grade/report/singleview/tests/screen_test.php
+++ b/grade/report/singleview/tests/screen_test.php
@@ -23,8 +23,9 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-
+global $CFG;
require_once(__DIR__ . '/fixtures/screen.php');
+require_once($CFG->libdir . '/gradelib.php');
defined('MOODLE_INTERNAL') || die();
/**
@@ -59,6 +60,8 @@ class gradereport_singleview_screen_testcase extends advanced_testcase {
$this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user1->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user2->id));
+ // Perform a regrade before creating the report.
+ grade_regrade_final_grades($course->id);
$screentest = new gradereport_singleview_screen_testable($course->id, 0, $group->id);
$groupusers = $screentest->test_load_users();
$this->assertCount(2, $groupusers);
@@ -89,4 +92,4 @@ class gradereport_singleview_screen_testcase extends advanced_testcase {
$users = $screentest->test_load_users();
$this->assertCount(2, $users);
}
-}
\ No newline at end of file
+}
diff --git a/grade/report/user/index.php b/grade/report/user/index.php
index 149879c328b..1e8460e24a0 100644
--- a/grade/report/user/index.php
+++ b/grade/report/user/index.php
@@ -79,9 +79,8 @@ if (!isset($USER->grade_last_report)) {
}
$USER->grade_last_report[$course->id] = 'user';
-
-//first make sure we have proper final grades - this must be done before constructing of the grade tree
-grade_regrade_final_grades($courseid);
+// First make sure we have proper final grades.
+grade_regrade_final_grades_if_required($course);
if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all student reports
$groupmode = groups_get_course_groupmode($course); // Groups are being used
diff --git a/grade/report/user/lib.php b/grade/report/user/lib.php
index 0f35f8289c4..65f66a6ebca 100644
--- a/grade/report/user/lib.php
+++ b/grade/report/user/lib.php
@@ -1163,9 +1163,6 @@ function grade_report_user_profilereport($course, $user, $viewasuser = false) {
$context = context_course::instance($course->id);
- //first make sure we have proper final grades - this must be done before constructing of the grade tree
- grade_regrade_final_grades($course->id);
-
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'user', 'courseid'=>$course->id, 'userid'=>$user->id));
// Create a report instance
diff --git a/grade/report/user/tests/behat/view_usereport.feature b/grade/report/user/tests/behat/view_usereport.feature
index b4051b86d58..9bc1f8f2fa8 100644
--- a/grade/report/user/tests/behat/view_usereport.feature
+++ b/grade/report/user/tests/behat/view_usereport.feature
@@ -14,7 +14,5 @@ Feature: We can use the user report
And I follow "Course 1"
And I navigate to "Grades" node in "Course administration"
And I select "User report" from the "Grade report" singleselect
- And I press "Go"
And I select "All users (0)" from the "Select all or one user" singleselect
- And I click on "Go" "button" in the "#choosegradeuser" "css_element"
Then I should see "No students enrolled in this course yet"
diff --git a/grade/tests/behat/grade_UI_settings.feature b/grade/tests/behat/grade_UI_settings.feature
index 72b1feba548..e01b9282c7c 100644
--- a/grade/tests/behat/grade_UI_settings.feature
+++ b/grade/tests/behat/grade_UI_settings.feature
@@ -28,7 +28,7 @@ Feature: Site settings can be used to hide parts of the gradebook UI
When I click on "Edit assign Assignment1" "link"
And I should see "Minimum grade"
Then I navigate to "General settings" node in "Site administration > Grades"
- And I click on "Show minimum grade" "checkbox"
+ And I set the field "Show minimum grade" to "0"
And I press "Save changes"
And I am on site homepage
And I follow "Course 1"
@@ -40,7 +40,7 @@ Feature: Site settings can be used to hide parts of the gradebook UI
Scenario: Hide calculation icons
And "Edit calculation for Course total" "link" should exist
When I navigate to "Grader report" node in "Site administration > Grades > Report settings"
- And I click on "Show calculations" "checkbox"
+ And I set the field "Show calculations" to "0"
And I press "Save changes"
And I am on site homepage
And I follow "Course 1"
@@ -51,7 +51,7 @@ Feature: Site settings can be used to hide parts of the gradebook UI
Scenario: Disable category overriding
And "tr .course input[type='text']" "css_element" should exist
Then I navigate to "Grade category settings" node in "Site administration > Grades"
- And I click on "Allow category grades to be manually overridden" "checkbox"
+ And I set the field "Allow category grades to be manually overridden" to "0"
And I press "Save changes"
And I am on site homepage
And I follow "Course 1"
diff --git a/grade/tests/behat/grade_override_letter.feature b/grade/tests/behat/grade_override_letter.feature
index 12ac7d38795..6abdcb9e0d4 100644
--- a/grade/tests/behat/grade_override_letter.feature
+++ b/grade/tests/behat/grade_override_letter.feature
@@ -204,4 +204,4 @@ Feature: Grade letters can be overridden
| 89.99 % | 85.00 % | β |
| 84.99 % | 70.00 % | γ |
| 69.99 % | 55.00 % | δ |
- | 54.99 % | 0.00 % | Ω |
\ No newline at end of file
+ | 54.99 % | 0.00 % | Ω |
diff --git a/grade/tests/behat/grade_point_maximum.feature b/grade/tests/behat/grade_point_maximum.feature
index 107030221f2..c750f819603 100644
--- a/grade/tests/behat/grade_point_maximum.feature
+++ b/grade/tests/behat/grade_point_maximum.feature
@@ -76,7 +76,6 @@ Feature: We can change the grading type and maximum grade point values
And the "Maximum grade" "field" should be disabled
And I press "Save and return to course"
- @javascript
Scenario: Create an activity with a maximum grade point value higher than the system maximum
When I follow "Test Assignment 1"
And I follow "Edit settings"
@@ -87,7 +86,6 @@ Feature: We can change the grading type and maximum grade point values
Then I should see "Invalid grade value. This must be an integer between 1 and 900"
And I press "Cancel"
- @javascript
Scenario: Create an activity with a valid maximum grade point and then change the system maximum to be lower
When I follow "Test Assignment 1"
And I follow "Edit settings"
diff --git a/grade/tests/behat/grade_scales_aggregation.feature b/grade/tests/behat/grade_scales_aggregation.feature
index 2c74e52dd00..b866294391f 100644
--- a/grade/tests/behat/grade_scales_aggregation.feature
+++ b/grade/tests/behat/grade_scales_aggregation.feature
@@ -36,7 +36,6 @@ Feature: Control the aggregation of the scales
| grade_includescalesinaggregation | 0 |
And I log out
- @javascript
Scenario Outline: Scales can be excluded from aggregation
Given I log in as "teacher1"
And I follow "Course 1"
diff --git a/grade/tests/behat/grade_single_item_scales.feature b/grade/tests/behat/grade_single_item_scales.feature
index 190e1f7d5d0..ed3a96ab04a 100644
--- a/grade/tests/behat/grade_single_item_scales.feature
+++ b/grade/tests/behat/grade_single_item_scales.feature
@@ -56,7 +56,6 @@ Feature: View gradebook when single item scales are used
And I follow "Grader report"
And I turn editing mode on
- @javascript
Scenario: Test displaying single item scales in gradebook in aggregation method Natural
When I turn editing mode off
Then the following should exist in the "user-grades" table:
@@ -67,36 +66,33 @@ Feature: View gradebook when single item scales are used
| Range | Ace!–Ace! | 0.00–1.00 | 0.00–1.00 |
| Overall average | Ace! | 1.00 | 1.00 |
And I follow "User report"
- And I set the field "Select all or one user" to "Student 1"
+ And I select "Student 1" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Contribution to course total |
| Test assignment one | Ace! | Ace!–Ace! | 100.00 % |
| Sub category 1 total| 1.00 | 0–1 | - |
| Course total | 1.00 | 0–1 | - |
- And I set the field "Select all or one user" to "Student 2"
+ And I select "Student 2" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Contribution to course total |
| Test assignment one | - | Ace!–Ace! | - |
| Sub category 1 total| - | 0–1 | - |
| Course total | - | 0–1 | - |
- And I set the field "jump" to "Gradebook setup"
+ And I select "Gradebook setup" from the "jump" singleselect
And the following should exist in the "grade_edit_tree_table" table:
| Name | Max grade |
| Test assignment one | 1.00 |
| Sub category 1 total| 1.00 |
| Course total | 1.00 |
- @javascript
Scenario Outline: Test displaying single item scales in gradebook in all other aggregation methods
When I follow "Edit Course 1"
And I set the field "Aggregation" to ""
And I press "Save changes"
And I follow "Edit Sub category 1"
- And I expand all fieldsets
- And I set the field "Aggregation" to ""
- And I set the field "Category name" to "Sub category ()"
- # And I set the field "Maximum grade" to "5"
- # And I set the field "Minimum grade" to "1"
+ And I set the following fields to these values:
+ | Aggregation | |
+ | Category name | Sub category () |
And I press "Save changes"
And I turn editing mode off
Then the following should exist in the "user-grades" table:
@@ -108,19 +104,18 @@ Feature: View gradebook when single item scales are used
| Range | Ace!–Ace! | 0.00–100.0 | 0.00–100.00 |
| Overall average | Ace! | | |
And I follow "User report"
- And I set the field "Select all or one user" to "Student 1"
- And I click on "Select all or one user" "select"
+ And I select "Student 1" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Grade | Range | Contribution to course total |
| Test assignment one | Ace! | Ace!–Ace! | |
| Sub category () total. | | 0–100 | - |
| Course total. | | 0–100 | - |
- And I set the field "jump" to "Gradebook setup"
+ And I select "Gradebook setup" from the "jump" singleselect
And the following should exist in the "grade_edit_tree_table" table:
- | Name | Max grade |
- | Test assignment one | Ace! (1) |
+ | Name | Max grade |
+ | Test assignment one | Ace! (1) |
| Sub category () total. | 100.00 |
- | Course total. | 100.00 |
+ | Course total. | 100.00 |
Examples:
| aggregation | contrib1 | cattotal1 | coursetotal1 | catavg | overallavg |
diff --git a/grade/tests/behat/grade_to_pass.feature b/grade/tests/behat/grade_to_pass.feature
index 34360b1e09f..7125b6232b2 100644
--- a/grade/tests/behat/grade_to_pass.feature
+++ b/grade/tests/behat/grade_to_pass.feature
@@ -45,7 +45,6 @@ Feature: We can set the grade to pass value
Then I should see "The grade to pass can not be greater than the maximum possible grade 50"
And I press "Cancel"
- @javascript
Scenario: Set a valid grade to pass for an assignment activity using points
When I turn editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
@@ -69,7 +68,6 @@ Feature: We can set the grade to pass value
And I click on "Edit assign Test Assignment 1" "link"
And the field "Grade to pass" matches value "30"
- @javascript
Scenario: Set a valid grade to pass for an assignment activity using scales
When I turn editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
@@ -81,7 +79,7 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit assign Test Assignment 1" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "3"
And I set the field "Grade to pass" to "4"
And I press "Save changes"
@@ -90,7 +88,6 @@ Feature: We can set the grade to pass value
And I follow "Edit settings"
And the field "Grade to pass" matches value "4"
- @javascript
Scenario: Set a invalid grade to pass for an assignment activity using scales
When I turn editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
@@ -101,7 +98,6 @@ Feature: We can set the grade to pass value
| Grade to pass | 10 |
Then I should see "The grade to pass can not be greater than the maximum possible grade 4"
- @javascript
Scenario: Set a valid grade to pass for workshop activity
When I turn editing mode on
And I add a "Workshop" to section "1" and I fill the form with:
@@ -114,12 +110,12 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit workshop Test Workshop 1 (submission)" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "40"
And I set the field "Grade to pass" to "45"
And I press "Save changes"
And I click on "Edit workshop Test Workshop 1 (assessment)" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
And the field "Grade to pass" matches value "10"
And I set the field "Grade to pass" to "15"
And I press "Save changes"
@@ -129,7 +125,6 @@ Feature: We can set the grade to pass value
And the field "Submission grade to pass" matches value "45"
And the field "Assessment grade to pass" matches value "15"
- @javascript
Scenario: Set an invalid grade to pass for workshop activity
When I turn editing mode on
And I add a "Workshop" to section "1" and I fill the form with:
@@ -142,7 +137,6 @@ Feature: We can set the grade to pass value
Then "The grade to pass can not be greater than the maximum possible grade 80" "text" should exist in the "#fitem_id_submissiongradepass .error" "css_element"
Then "The grade to pass can not be greater than the maximum possible grade 20" "text" should exist in the "#fitem_id_gradinggradepass .error" "css_element"
- @javascript
Scenario: Set a valid grade to pass for quiz activity
When I turn editing mode on
And I add a "Quiz" to section "1" and I fill the form with:
@@ -151,7 +145,7 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit quiz Test Quiz 1" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "9.5"
And I set the field "Grade to pass" to "8"
And I press "Save changes"
@@ -160,7 +154,6 @@ Feature: We can set the grade to pass value
And I follow "Edit settings"
And the field "Grade to pass" matches value "8.00"
- @javascript
Scenario: Set a valid grade to pass for lesson activity
When I turn editing mode on
And I add a "Lesson" to section "1" and I fill the form with:
@@ -170,7 +163,7 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit lesson Test Lesson 1" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "90"
And I set the field "Grade to pass" to "80"
And I press "Save changes"
@@ -179,7 +172,6 @@ Feature: We can set the grade to pass value
And I follow "Edit settings"
And the field "Grade to pass" matches value "80"
- @javascript
Scenario: Set a valid grade to pass for database activity
When I turn editing mode on
And I add a "Database" to section "1" and I fill the form with:
@@ -190,7 +182,7 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit data Test Database 1" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "90"
And I set the field "Grade to pass" to "80"
And I press "Save changes"
@@ -199,7 +191,6 @@ Feature: We can set the grade to pass value
And I follow "Edit settings"
And the field "Grade to pass" matches value "80"
- @javascript
Scenario: Set an invalid grade to pass for forum activity
When I turn editing mode on
And I add a "Forum" to section "1" and I fill the form with:
@@ -210,7 +201,6 @@ Feature: We can set the grade to pass value
| scale[modgrade_point] | 60 |
Then I should see "The grade to pass can not be greater than the maximum possible grade 60"
- @javascript
Scenario: Set a valid grade to pass for forum activity
When I turn editing mode on
And I add a "Forum" to section "1" and I fill the form with:
@@ -221,7 +211,7 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit forum Test Forum 1" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "90"
And I set the field "Grade to pass" to "80"
And I press "Save changes"
@@ -230,7 +220,6 @@ Feature: We can set the grade to pass value
And I follow "Edit settings"
And the field "Grade to pass" matches value "80"
- @javascript
Scenario: Set a valid grade to pass for glossary activity
When I turn editing mode on
And I add a "Glossary" to section "1" and I fill the form with:
@@ -241,7 +230,7 @@ Feature: We can set the grade to pass value
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I click on "Edit glossary Test Glossary 1" "link"
- And I follow "Show more..."
+ And I expand all fieldsets
Then the field "Grade to pass" matches value "90"
And I set the field "Grade to pass" to "80"
And I press "Save changes"
diff --git a/lang/en/error.php b/lang/en/error.php
index 32aded39cda..2dc689f8214 100644
--- a/lang/en/error.php
+++ b/lang/en/error.php
@@ -254,6 +254,7 @@ $string['filternotinstalled'] = 'Filter {$a} is not currently installed';
$string['forumblockingtoomanyposts'] = 'You have exceeded the posting threshold set for this forum';
$string['generalexceptionmessage'] = 'Exception - {$a}';
$string['gradepubdisable'] = 'Grade publishing disabled';
+$string['gradesneedregrading'] = 'The course grades need to be recalculated';
$string['gradecantregrade'] = 'An error occurred during grade calculation: {$a}';
$string['groupalready'] = 'User already belongs to group {$a}';
$string['groupexistforcourse'] = 'Group "{$a}" already exists for this course';
diff --git a/lang/en/grades.php b/lang/en/grades.php
index 4089b5e4f65..f37a5fe5e66 100644
--- a/lang/en/grades.php
+++ b/lang/en/grades.php
@@ -616,6 +616,7 @@ $string['rawpct'] = 'Raw %';
$string['real'] = 'Real';
$string['realletter'] = 'Real (letter)';
$string['realpercentage'] = 'Real (percentage)';
+$string['recalculatinggrades'] = 'Recalculating grades';
$string['recovergradesdefault'] = 'Recover grades default';
$string['recovergradesdefault_help'] = 'By default recover old grades when re-enrolling a user in a course.';
$string['refreshpreview'] = 'Refresh preview';
diff --git a/lib/classes/progress/display.php b/lib/classes/progress/display.php
index 4e3b46ff501..b7974bc0b56 100644
--- a/lib/classes/progress/display.php
+++ b/lib/classes/progress/display.php
@@ -126,6 +126,11 @@ class display extends base {
$this->direction = -$this->direction;
$this->currentstate += 2 * $this->direction;
}
+ $buffersize = ini_get('output_buffering');
+ if ($buffersize) {
+ // Force the buffer full.
+ echo str_pad('', $buffersize);
+ }
}
// Get progress.
diff --git a/lib/gradelib.php b/lib/gradelib.php
index 6dfa2279d75..c50ecd9abe9 100644
--- a/lib/gradelib.php
+++ b/lib/gradelib.php
@@ -325,6 +325,86 @@ function grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $item
return false; //grade items not found
}
+/**
+ * Return true if the course needs regrading.
+ *
+ * @param int $courseid The course ID
+ * @return bool true if course grades need updating.
+ */
+function grade_needs_regrade_final_grades($courseid) {
+ $course_item = grade_item::fetch_course_item($courseid);
+ return $course_item->needsupdate;
+}
+
+/**
+ * Return true if the regrade process is likely to be time consuming and
+ * will therefore require the progress bar.
+ *
+ * @param int $courseid The course ID
+ * @return bool Whether the regrade process is likely to be time consuming
+ */
+function grade_needs_regrade_progress_bar($courseid) {
+ global $DB;
+ $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', '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.
+ return $gradecount > 100;
+}
+
+/**
+ * Check whether regarding of final grades is required and, if so, perform the regrade.
+ *
+ * If the regrade is expected to be time consuming (see grade_needs_regrade_progress_bar), then this
+ * function will output the progress bar, and redirect to the current PAGE->url after regrading
+ * 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
+ * @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, callable $callback = null) {
+ global $PAGE, $OUTPUT;
+
+ if (!grade_needs_regrade_final_grades($course->id)) {
+ return false;
+ }
+
+ if (grade_needs_regrade_progress_bar($course->id)) {
+ $PAGE->set_heading($course->fullname);
+ echo $OUTPUT->header();
+ echo $OUTPUT->heading(get_string('recalculatinggrades', 'grades'));
+ $progress = new \core\progress\display(true);
+ grade_regrade_final_grades($course->id, null, null, $progress);
+
+ if ($callback) {
+ //
+ $url = call_user_func($callback);
+ }
+
+ if (empty($url)) {
+ $url = $PAGE->url;
+ }
+
+ echo $OUTPUT->continue_button($url);
+ echo $OUTPUT->footer();
+ die();
+ } else {
+ $result = grade_regrade_final_grades($course->id);
+ if ($callback) {
+ call_user_func($callback);
+ }
+ return $result;
+ }
+}
+
/**
* Returns grading information for given activity, optionally with user grades
* Manual, course or category items can not be queried.
@@ -1011,14 +1091,19 @@ function grade_recover_history_grades($userid, $courseid) {
* @param int $courseid The course ID
* @param int $userid If specified try to do a quick regrading of the grades of this user only
* @param object $updated_item Optional grade item to be marked for regrading
+ * @param \core\progress\base $progress If provided, will be used to update progress on this long operation.
* @return bool true if ok, array of errors if problems found. Grade item id => error message
*/
-function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null) {
+function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null, $progress=null) {
// This may take a very long time.
\core_php_time_limit::raise();
$course_item = grade_item::fetch_course_item($courseid);
+ if ($progress == null) {
+ $progress = new \core\progress\none();
+ }
+
if ($userid) {
// one raw grade updated for one user
if (empty($updated_item)) {
@@ -1072,6 +1157,18 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
$depends_on[$gid] = $grade_items[$gid]->depends_on();
}
+ $progresstotal = 0;
+ $progresscurrent = 0;
+
+ // This progress total might not be 100% accurate, because more things might get marked as needsupdate
+ // during the process.
+ foreach ($grade_items as $item) {
+ if ($item->needsupdate) {
+ $progresstotal++;
+ }
+ }
+ $progress->start_progress('regrade_course', $progresstotal);
+
$errors = array();
$finalids = array();
$gids = array_keys($grade_items);
@@ -1088,6 +1185,16 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
$finalids[] = $gid; // we can make it final - does not need update
continue;
}
+ $thisprogress = $progresstotal;
+ foreach ($grade_items as $item) {
+ if ($item->needsupdate) {
+ $thisprogress--;
+ }
+ }
+ // Clip between $progresscurrent and $progresstotal.
+ $thisprogress = max(min($thisprogress, $progresstotal), $progresscurrent);
+ $progress->progress($thisprogress);
+ $progresscurrent = $thisprogress;
$doupdate = true;
foreach ($depends_on[$gid] as $did) {
@@ -1131,6 +1238,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
break; // Found error.
}
}
+ $progress->end_progress();
if (count($errors) == 0) {
if (empty($userid)) {