Example #1
0
 /**
  * Test upgrade_letter_boundary_needs_freeze function.
  */
 public function test_upgrade_letter_boundary_needs_freeze()
 {
     global $CFG;
     $this->resetAfterTest();
     require_once $CFG->libdir . '/db/upgradelib.php';
     $courses = array();
     $contexts = array();
     for ($i = 0; $i < 3; $i++) {
         $courses[] = $this->getDataGenerator()->create_course();
         $contexts[] = context_course::instance($courses[$i]->id);
     }
     // Course one is not using a letter boundary.
     $this->assertFalse(upgrade_letter_boundary_needs_freeze($contexts[0]));
     // Let's make course 2 use the bad boundary.
     $this->assign_bad_letter_boundary($contexts[1]->id);
     $this->assertTrue(upgrade_letter_boundary_needs_freeze($contexts[1]));
     // Course 3 has letter boundaries that are fine.
     $this->assign_good_letter_boundary($contexts[2]->id);
     $this->assertFalse(upgrade_letter_boundary_needs_freeze($contexts[2]));
     // Try the system context not using a letter boundary.
     $systemcontext = context_system::instance();
     $this->assertFalse(upgrade_letter_boundary_needs_freeze($systemcontext));
 }
Example #2
0
/**
 * Marks all courses that require rounded grade items be updated.
 *
 * Used during upgrade and in course restore process.
 *
 * This upgrade script is needed because it has been decided that if a grade is rounded up, and it will changed a letter
 * grade or satisfy a course completion grade criteria, then it should be set as so, and the letter will be awarded and or
 * the course completion grade will be awarded.
 *
 * @param int $courseid Specify a course ID to run this script on just one course.
 */
function upgrade_course_letter_boundary($courseid = null)
{
    global $DB, $CFG;
    $coursesql = '';
    $params = array('contextlevel' => CONTEXT_COURSE);
    if (!empty($courseid)) {
        $coursesql = 'AND c.id = :courseid';
        $params['courseid'] = $courseid;
    }
    // Check to see if the system letter boundaries are borked.
    $systemcontext = context_system::instance();
    $systemneedsfreeze = upgrade_letter_boundary_needs_freeze($systemcontext);
    // 3, 13, 23, 31, and 32 are the grade display types that incorporate showing letters. See lib/grade/constants/php.
    $systemletters = isset($CFG->grade_displaytype) && in_array($CFG->grade_displaytype, array(3, 13, 23, 31, 32));
    $contextselect = context_helper::get_preload_record_columns_sql('ctx');
    if ($systemletters && $systemneedsfreeze) {
        // Select courses with no grade setting for display and a grade item that is using the default display,
        // but have not altered the course letter boundary configuration. These courses are definitely affected.
        $sql = "SELECT DISTINCT c.id AS courseid\n                  FROM {course} c\n                  JOIN {grade_items} gi ON c.id = gi.courseid\n                  JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel\n             LEFT JOIN {grade_settings} gs ON gs.courseid = c.id AND gs.name = 'displaytype'\n             LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id\n                 WHERE gi.display = 0 AND (gs.value is NULL)\n                 AND gl.id is NULL {$coursesql}";
        $affectedcourseids = $DB->get_recordset_sql($sql, $params);
        foreach ($affectedcourseids as $courseid) {
            set_config('gradebook_calculations_freeze_' . $courseid->courseid, 20160518);
        }
        $affectedcourseids->close();
    }
    if ($systemletters || $systemneedsfreeze) {
        // If the system letter boundary is okay proceed to check grade item and course grade display settings.
        $sql = "SELECT DISTINCT c.id AS courseid, {$contextselect}\n                  FROM {course} c\n                  JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel\n                  JOIN {grade_items} gi ON c.id = gi.courseid\n             LEFT JOIN {grade_settings} gs ON c.id = gs.courseid AND gs.name = 'displaytype'\n             LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id\n                 WHERE gi.display IN (3, 13, 23, 31, 32)\n                    OR (" . $DB->sql_compare_text('gs.value') . " IN ('3', '13', '23', '31', '32'))\n                    OR gl.id is NOT NULL\n                       {$coursesql}";
    } else {
        // There is no site setting for letter grades. Just check the modified letter boundaries.
        $sql = "SELECT DISTINCT c.id AS courseid, {$contextselect}\n                  FROM {grade_letters} l, {course} c\n                  JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel\n                 WHERE l.contextid = ctx.id\n                   AND ctx.instanceid = c.id\n                   {$coursesql}";
    }
    $potentialcourses = $DB->get_recordset_sql($sql, $params);
    foreach ($potentialcourses as $value) {
        $gradebookfreeze = 'gradebook_calculations_freeze_' . $value->courseid;
        // Check also if this course id has already been frozen.
        // If we already have this course ID then move on to the next record.
        if (!property_exists($CFG, $gradebookfreeze)) {
            // Check for 57 letter grade issue.
            context_helper::preload_from_record($value);
            $coursecontext = context_course::instance($value->courseid);
            if (upgrade_letter_boundary_needs_freeze($coursecontext)) {
                // We have a course with a possible score standardisation problem. Flag for freeze.
                // Flag this course as being frozen.
                set_config('gradebook_calculations_freeze_' . $value->courseid, 20160518);
            }
        }
    }
    $potentialcourses->close();
}