forked from moodle/moodle
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MDL-75878 Course: Adding graded activity too slow when lots of grades
Adding an activity with a grade item previously triggered a course regrade, which can be extremely slow. This change makes it so that on courses where regrading is slow, when you add an activity that requires regrading, it takes you to an intermediate screen with a progress bar. This change also fixes a bug in the existing grade overview report, which shows grades across multiple courses, but previously only checked, and if necessary regraded, one course.
- Loading branch information
1 parent
12e9d9e
commit fbd61d1
Showing
8 changed files
with
243 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
// This file is part of Moodle - http://moodle.org/ | ||
// | ||
// Moodle is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// Moodle is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
/** | ||
* Regrades a module that has been added or updated when it might take a long time. | ||
* | ||
* A progress bar will be displayed in that case, and then the user can click 'Continue' to proceed. | ||
* If for some reason you get to this page when regrading will not take a long time, then it will | ||
* redirect immediately. | ||
* | ||
* @package core_course | ||
* @copyright 2022 The Open University | ||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | ||
*/ | ||
|
||
define('NO_OUTPUT_BUFFERING', true); | ||
require('../config.php'); | ||
require_once($CFG->libdir . '/gradelib.php'); | ||
|
||
$cmid = required_param('id', PARAM_INT); | ||
$urlpath = required_param('url', PARAM_LOCALURL); | ||
$url = new moodle_url($urlpath); | ||
|
||
// Check that an absolute url/path was specified e.g. /course/view.php (it probably isn't a | ||
// security risk to allow a relative one, but isn't necessary here). | ||
if (!$url->get_host()) { | ||
throw new moodle_exception('missingparam', 'error', '', 'url'); | ||
} | ||
|
||
// Get course. | ||
[$course, $cm] = get_course_and_cm_from_cmid($cmid); | ||
$context = \context_module::instance($cm->id); | ||
|
||
// Set up page for display. | ||
$PAGE->set_url(new moodle_url('/course/modregrade.php', ['id' => $cmid, 'url' => $url])); | ||
$PAGE->set_context($context); | ||
$PAGE->set_title($course->shortname . ': ' . get_string('recalculatinggrades', 'grades')); | ||
|
||
// Security check: must be logged in with manage activities permission. | ||
require_login($course, false, $cm); | ||
require_capability('moodle/course:manageactivities', $context); | ||
|
||
// Do the regrade if necessary. | ||
grade_regrade_final_grades_if_required($course); | ||
|
||
// Redirect back to the target URL. | ||
redirect($url); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<?php | ||
// This file is part of Moodle - http://moodle.org/ | ||
// | ||
// Moodle is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// Moodle is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
namespace gradereport_overview; | ||
|
||
/** | ||
* Overview grade report lib functions unit tests | ||
* | ||
* @package gradereport_overview | ||
* @copyright 2023 The Open University | ||
* @covers \grade_report_overview | ||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | ||
*/ | ||
class lib_test extends \externallib_advanced_testcase { | ||
|
||
/** | ||
* Require the library file we're about to test, and other requirements. | ||
*/ | ||
protected function setUp(): void { | ||
global $CFG; | ||
require_once($CFG->dirroot . '/grade/report/overview/lib.php'); | ||
require_once($CFG->dirroot . '/grade/querylib.php'); | ||
} | ||
|
||
/** | ||
* Data provider for true or false value. | ||
* | ||
* @return array Two options, one with true and one with false | ||
*/ | ||
public function true_or_false(): array { | ||
return [ | ||
[true], | ||
[false] | ||
]; | ||
} | ||
|
||
/** | ||
* Tests the regrade_all_courses_if_needed function, which is supposed to regrade all the | ||
* courses that the current user is enrolled on (if they need update). | ||
* | ||
* This is tested with both frontend and backend - the frontend option should not actually | ||
* do the progress bar/continue button (which can't be tested from here because it calls exit) | ||
* because these courses are small. | ||
* | ||
* @dataProvider true_or_false | ||
* @param bool $frontend True to use the front-end parameter to the function under test | ||
*/ | ||
public function test_regrade_all_courses_if_needed(bool $frontend): void { | ||
global $DB; | ||
$this->resetAfterTest(true); | ||
|
||
$generator = $this->getDataGenerator(); | ||
|
||
// Create 3 courses and a test user. The test user belongs to 2 of them, while another user | ||
// belongs to the other course. | ||
$user = $generator->create_user(); | ||
$otheruser = $generator->create_user(); | ||
$course1 = $generator->create_course(); | ||
$generator->enrol_user($user->id, $course1->id, 'student'); | ||
$course2 = $generator->create_course(); | ||
$generator->enrol_user($otheruser->id, $course2->id, 'student'); | ||
$course3 = $generator->create_course(); | ||
$generator->enrol_user($user->id, $course3->id, 'student'); | ||
|
||
// We need permission to create grades (even though it's a data generator). | ||
$this->setAdminUser(); | ||
|
||
// Set up each course grade. | ||
foreach ([$course1, $course2, $course3] as $course) { | ||
// Create an assignment and get its grade item. | ||
$assign = $generator->create_module('assign', ['course' => $course->id]); | ||
$modinfo = get_fast_modinfo($course->id); | ||
$cm = $modinfo->get_cm($assign->cmid); | ||
$items = grade_get_grade_items_for_activity($cm, true); | ||
$item = reset($items); | ||
|
||
// Set a grade in the assignment, either for the normal test user or the other user | ||
// depending on course. | ||
if ($course === $course2) { | ||
$userid = $otheruser->id; | ||
} else { | ||
$userid = $user->id; | ||
} | ||
$generator->create_grade_grade([ | ||
'itemid' => $item->id, | ||
'userid' => $userid, | ||
'teamsubmission' => false, | ||
'attemptnumber' => 0, | ||
'grade' => 50 | ||
]); | ||
|
||
// Bodge the final grade so that it needs regrading and is set wrong. | ||
$course->gradeitemid = $DB->get_field('grade_items', 'id', | ||
['courseid' => $course->id, 'itemtype' => 'course'], MUST_EXIST); | ||
$DB->set_field('grade_items', 'needsupdate', 1, ['id' => $course->gradeitemid]); | ||
$DB->set_field('grade_grades', 'finalgrade', 25.0, ['itemid' => $course->gradeitemid]); | ||
} | ||
|
||
// Construct the overview report and call regrade_all_courses_if_needed. | ||
$gpr = new \stdClass(); | ||
$report = new \grade_report_overview($user->id, $gpr, ''); | ||
$report->regrade_all_courses_if_needed($frontend); | ||
|
||
// This should have regraded courses 1 and 3, but not 2 (because the user doesn't belong). | ||
$this->assertEqualsWithDelta(50.0, $DB->get_field('grade_grades', 'finalgrade', | ||
['itemid' => $course1->gradeitemid]), 1.0); | ||
$this->assertEqualsWithDelta(25.0, $DB->get_field('grade_grades', 'finalgrade', | ||
['itemid' => $course2->gradeitemid]), 1.0); | ||
$this->assertEqualsWithDelta(50.0, $DB->get_field('grade_grades', 'finalgrade', | ||
['itemid' => $course3->gradeitemid]), 1.0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters