Merge branch 'MDL-56567-master' of https://github.com/matthewhilton/moodle

This commit is contained in:
Ilya Tregubov
2022-10-17 09:04:48 +03:00
11 changed files with 418 additions and 17 deletions
@@ -0,0 +1,69 @@
<?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/>.
/**
* Course competency override grade element.
*
* @package tool_lp
* @copyright 2022 Matthew Hilton <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/form/advcheckbox.php');
/**
* Course competency override grade element.
*
* @package tool_lp
* @copyright 2022 Matthew Hilton <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_lp_course_competency_overridegrade_form_element extends MoodleQuickForm_advcheckbox {
/**
* Constructor
*
* @param string $elementname Element name
* @param mixed $elementlabel Label(s) for an element
* @param array $options Options to control the element's display
*/
public function __construct($elementname=null, $elementlabel=null, $options=[]) {
if ($elementname == null) {
// This is broken quickforms messing with the constructors.
return;
}
if (!empty($options['cmid'])) {
$cmid = $options['cmid'];
$current = \core_competency\api::list_course_module_competencies_in_course_module($cmid);
// Note: We just pick the override grade value set on the first course_module_competency.
// Because in the UI we force them to be the same for all.
if (!empty($current)) {
$one = array_pop($current);
$this->setValue($one->get('overridegrade'));
}
}
parent::__construct($elementname, $elementlabel);
}
}
+1
View File
@@ -165,6 +165,7 @@ $string['nouserevidence'] = 'No evidence of prior learning has been added yet.';
$string['nouserplans'] = 'No learning plans have been created yet.';
$string['oneplanwascreated'] = 'A learning plan was created';
$string['outcome'] = 'Outcome';
$string['overridegrade'] = 'Override existing competency grade when completed.';
$string['path'] = 'Path:';
$string['parentcompetency'] = 'Parent';
$string['parentcompetency_edit'] = 'Edit parent';
+10 -1
View File
@@ -161,6 +161,12 @@ function tool_lp_coursemodule_standard_elements($formwrapper, $mform) {
'tool_lp_course_competency_rule_form_element');
// Reuse the same options.
$mform->addElement('course_competency_rule', 'competency_rule', get_string('uponcoursemodulecompletion', 'tool_lp'), $options);
$overrideelementfile = "$CFG->dirroot/$CFG->admin/tool/lp/classes/course_competency_overridegrade_form_element.php";
MoodleQuickForm::registerElementType('course_competency_overridegrade', $overrideelementfile,
'tool_lp_course_competency_overridegrade_form_element');
$mform->addElement('course_competency_overridegrade', 'override_grade', get_string('overridegrade', 'tool_lp'), $options);
$mform->hideIf('override_grade', 'competency_rule', 'noteq', \core_competency\competency::OUTCOME_COMPLETE + 1);
}
/**
@@ -201,10 +207,13 @@ function tool_lp_coursemodule_edit_post_actions($data, $course) {
}
if (isset($data->competency_rule)) {
$overridegrade = isset($data->override_grade) ? $data->override_grade : false;
// Now update the rules for each course_module_competency.
$current = \core_competency\api::list_course_module_competencies_in_course_module($data->coursemodule);
foreach ($current as $coursemodulecompetency) {
\core_competency\api::set_course_module_competency_ruleoutcome($coursemodulecompetency, $data->competency_rule);
\core_competency\api::set_course_module_competency_ruleoutcome($coursemodulecompetency, $data->competency_rule,
$overridegrade);
}
}
+2 -2
View File
@@ -1843,10 +1843,10 @@ class backup_activity_competencies_structure_step extends backup_structure_step
$wrapper->add_child($competencies);
$competency = new backup_nested_element('competency', null, array('idnumber', 'ruleoutcome',
'sortorder', 'frameworkidnumber'));
'sortorder', 'frameworkidnumber', 'overridegrade'));
$competencies->add_child($competency);
$sql = 'SELECT c.idnumber, cmc.ruleoutcome, cmc.sortorder, f.idnumber AS frameworkidnumber
$sql = 'SELECT c.idnumber, cmc.ruleoutcome, cmc.overridegrade, cmc.sortorder, f.idnumber AS frameworkidnumber
FROM {' . \core_competency\course_module_competency::TABLE . '} cmc
JOIN {' . \core_competency\competency::TABLE . '} c ON c.id = cmc.competencyid
JOIN {' . \core_competency\competency_framework::TABLE . '} f ON f.id = c.competencyframeworkid
+1
View File
@@ -3738,6 +3738,7 @@ class restore_activity_competencies_structure_step extends restore_structure_ste
// Sortorder is ignored by precaution, anyway we should walk through the records in the right order.
$record = (object) $params;
$record->ruleoutcome = $data->ruleoutcome;
$record->overridegrade = $data->overridegrade;
$coursemodulecompetency = new \core_competency\course_module_competency(0, $record);
$coursemodulecompetency->create();
}
+27 -12
View File
@@ -1582,9 +1582,11 @@ class api {
*
* @param int|course_module_competency $coursemodulecompetencyorid The course_module_competency, or its ID.
* @param int $ruleoutcome The value of ruleoutcome.
* @param bool $overridegrade If true, will override existing grades in related competencies.
* @return bool True on success.
*/
public static function set_course_module_competency_ruleoutcome($coursemodulecompetencyorid, $ruleoutcome) {
public static function set_course_module_competency_ruleoutcome($coursemodulecompetencyorid, $ruleoutcome,
$overridegrade = false) {
static::require_enabled();
$coursemodulecompetency = $coursemodulecompetencyorid;
if (!is_object($coursemodulecompetency)) {
@@ -1599,6 +1601,8 @@ class api {
require_capability('moodle/competency:coursecompetencymanage', $context);
$coursemodulecompetency->set('ruleoutcome', $ruleoutcome);
$coursemodulecompetency->set('overridegrade', $overridegrade);
return $coursemodulecompetency->update();
}
@@ -4279,7 +4283,7 @@ class api {
*/
public static function add_evidence($userid, $competencyorid, $contextorid, $action, $descidentifier, $desccomponent,
$desca = null, $recommend = false, $url = null, $grade = null, $actionuserid = null,
$note = null) {
$note = null, $overridegrade = false) {
global $DB;
static::require_enabled();
@@ -4350,8 +4354,8 @@ class api {
$usercompetencycourse = user_competency_course::create_relation($userid, $competencyid, $courseid);
$usercompetencycourse->create();
}
// Only update the grade and proficiency if there is not already a grade.
if ($usercompetencycourse->get('grade') === null) {
// Only update the grade and proficiency if there is not already a grade or the override option is enabled.
if ($usercompetencycourse->get('grade') === null || $overridegrade) {
// Set grade.
$usercompetencycourse->set('grade', $grade);
// Set proficiency.
@@ -4363,8 +4367,8 @@ class api {
$setucgrade = $coursesettings->get('pushratingstouserplans');
if ($setucgrade) {
// Only push to user plans if there is not already a grade.
if ($usercompetency->get('grade') !== null) {
// Only push to user plans if there is not already a grade or the override option is enabled.
if ($usercompetency->get('grade') !== null && !$overridegrade) {
$setucgrade = false;
} else {
$ucgrade = $grade;
@@ -4374,8 +4378,9 @@ class api {
} else {
// When completing the competency we fetch the default grade from the competency. But we only mark
// the user competency when a grade has not been set yet. Complete is an action to use with automated systems.
if ($usercompetency->get('grade') === null) {
// the user competency when a grade has not been set yet or if override option is enabled.
// Complete is an action to use with automated systems.
if ($usercompetency->get('grade') === null || $overridegrade) {
$setucgrade = true;
$ucgrade = $grade;
$ucproficiency = $proficiency;
@@ -4498,7 +4503,7 @@ class api {
// The competency was marked as completed, apply the rules.
if ($wascompleted) {
self::apply_competency_rules_from_usercompetency($usercompetency, $competency);
self::apply_competency_rules_from_usercompetency($usercompetency, $competency, $overridegrade);
}
return $evidence;
@@ -4557,7 +4562,7 @@ class api {
* @return void
*/
protected static function apply_competency_rules_from_usercompetency(user_competency $usercompetency,
competency $competency = null) {
competency $competency = null, $overridegrade = false) {
// Perform some basic checks.
if (!$usercompetency->get('proficiency')) {
@@ -4624,7 +4629,12 @@ class api {
'evidence_competencyrule',
'core_competency',
null,
$recommend
$recommend,
null,
null,
null,
null,
$overridegrade
);
}
@@ -4659,6 +4669,7 @@ class api {
$action = null;
$recommend = false;
$strdesc = 'evidence_coursemodulecompleted';
$overridegrade = $coursemodulecompetency->get('overridegrade');
if ($outcome == course_module_competency::OUTCOME_NONE) {
continue;
@@ -4686,7 +4697,11 @@ class api {
'core_competency',
$cmname,
$recommend,
$url
$url,
null,
null,
null,
$overridegrade
);
}
}
@@ -71,6 +71,10 @@ class course_module_competency extends persistent {
'default' => self::OUTCOME_EVIDENCE,
'type' => PARAM_INT,
),
'overridegrade' => array(
'default' => false,
'type' => PARAM_BOOL
),
);
}
@@ -0,0 +1,289 @@
<?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 core_competency;
/**
* Competency ruleoutcome override grade tests
*
* @package core_competency
* @copyright 2022 Matthew Hilton <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class competency_override_test extends \advanced_testcase {
public function setUp(): void {
$this->resetAfterTest(true);
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
// Create user in course.
$c1 = $dg->create_course((object) ['enablecompletion' => true]);
$u1 = $dg->create_user();
$dg->enrol_user($u1->id, $c1->id);
// Create framework with three values.
$scale = $dg->create_scale(["scale" => "not,partially,fully"]);
$scaleconfiguration = json_encode([
['scaleid' => $scale->id],
['id' => 1, 'scaledefault' => 1, 'proficient' => 1]
]);
$framework = $lpg->create_framework([
'scaleid' => $scale->id,
'scaleconfiguration' => $scaleconfiguration
]);
$plan = $lpg->create_plan(['userid' => $u1->id]);
$comp1 = $lpg->create_competency([
'competencyframeworkid' => $framework->get('id'),
'scaleid' => $scale->id,
'scaleconfiguration' => $scaleconfiguration
]);
$comp2 = $lpg->create_competency([
'competencyframeworkid' => $framework->get('id'),
'scaleid' => $scale->id,
'scaleconfiguration' => $scaleconfiguration
]);
api::add_competency_to_plan($plan->get('id'), $comp1->get('id'));
api::add_competency_to_plan($plan->get('id'), $comp2->get('id'));
$lpg->create_course_competency([
'courseid' => $c1->id,
'competencyid' => $comp1->get('id'),
'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE,
]);
$lpg->create_course_competency([
'courseid' => $c1->id,
'competencyid' => $comp2->get('id'),
'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE,
]);
$label = $dg->create_module('label', ['course' => $c1, 'completion' => COMPLETION_VIEWED, 'completionview' => 1]);
$cm = get_coursemodule_from_instance('label', $label->id);
$completion = new \completion_info($c1);
$this->assertEquals(COMPLETION_ENABLED, $completion->is_enabled($cm));
// Link course module with the competency and setup a rule to complete the competency when the module is completed.
api::add_competency_to_course_module($cm, $comp1->get('id'));
api::add_competency_to_course_module($cm, $comp2->get('id'));
$coursemodulecomps = api::list_course_module_competencies_in_course_module($cm);
$this->assertCount(2, $coursemodulecomps);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE);
$this->course = $c1;
$this->user = $u1;
$this->scale = $scale;
$this->framework = $framework;
$this->plan = $plan;
$this->comp1 = $comp1;
$this->comp2 = $comp2;
$this->cm = $cm;
$this->completion = new \completion_info($c1);
$this->context = \context_course::instance($this->course->id);
}
/**
* Test ruleoutcome overridegrade is correctly applied when coursemodule completion is processed.
*
* @covers \core_competency\api::set_course_module_competency_ruleoutcome
*/
public function test_ruleoutcome_overridegrade(): void {
// Initially the competency (and hence all the child competencies) should not be complete for the user.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(0, $plancomp->usercompetency->get('grade'));
$this->assertEquals(0, $usercomp->get('grade'));
$this->assertEquals(0, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(0, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(0, $usercomp2->get('grade'));
$this->assertEquals(0, $coursecomp2->get('grade'));
// Update the course module completion state to complete and trigger a competency update.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// Comptency should now be complete for user, plan, and course now that the course module is completed.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(1, $plancomp->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp->get('grade'));
$this->assertEquals(1, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(1, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp2->get('grade'));
$this->assertEquals(1, $coursecomp2->get('grade'));
// Change the competency completion for the user by adding evidence.
api::add_evidence($this->user->id, $this->comp1, $this->context,
evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 2);
api::add_evidence($this->user->id, $this->comp2, $this->context,
evidence::ACTION_OVERRIDE, 'commentincontext', 'core', null, false, null, 2);
// After adding evidence, the competencies should now reflect the new grade value.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(2, $plancomp->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// Update the course module competency to incomplete. This will not change the competency status.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_INCOMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(2, $plancomp->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// Re-complete the course module, so that it attempts to re-complete the competencies.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// By default, this will not override the existing grade, so it should remain the same as before.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(2, $plancomp->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp->get('grade'));
$this->assertEquals(2, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// Update the completion rule for only competency 1 to $overridegrade = true.
$coursemodulecomps = api::list_course_module_competencies_in_course_module($this->cm);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE,
true);
// Mark as incomplete then re-complete the course module.
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_INCOMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// Because the rule is now set to override existing grades, the grade should have now updated as per the ruleoutcome.
// However the second competency didn't have this rule set, so it will not be overriden.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(1, $plancomp->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp->get('grade'));
$this->assertEquals(1, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(2, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(2, $usercomp2->get('grade'));
$this->assertEquals(2, $coursecomp2->get('grade'));
// If competency 2 is changed now to override and re-completed, it will update the same as competency 1.
api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE,
true);
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_INCOMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
$data = $this->completion->get_data($this->cm, false, $this->user->id);
$data->completionstate = COMPLETION_COMPLETE;
$data->timemodified = time();
$this->completion->internal_set_data($this->cm, $data);
// Now both the competencies have $overridegrade = true,
// they should both reflect the ruleoutcome after the completion above was processed.
[$coursecomp, $plancomp, $usercomp] = $this->get_related_competencies($this->comp1->get('id'));
$this->assertEquals(1, $plancomp->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp->get('grade'));
$this->assertEquals(1, $coursecomp->get('grade'));
[$coursecomp2, $plancomp2, $usercomp2] = $this->get_related_competencies($this->comp2->get('id'));
$this->assertEquals(1, $plancomp2->usercompetency->get('grade'));
$this->assertEquals(1, $usercomp2->get('grade'));
$this->assertEquals(1, $coursecomp2->get('grade'));
}
/**
* Test competency backup and restore correctly restores the ruleoutcome overridegrade value.
*
* @covers \core_competency\api::set_course_module_competency_ruleoutcome
*/
public function test_override_backup_restore(): void {
global $CFG;
require_once($CFG->dirroot . '/course/externallib.php');
// Set one to override grade and another to not override grade.
$coursemodulecomps = api::list_course_module_competencies_in_course_module($this->cm);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[0], \core_competency\course_competency::OUTCOME_COMPLETE,
false);
api::set_course_module_competency_ruleoutcome($coursemodulecomps[1], \core_competency\course_competency::OUTCOME_COMPLETE,
true);
// Duplicate the course (backup and restore).
$duplicated = \core_course_external::duplicate_course($this->course->id, 'test', 'test', $this->course->category);
// Get the new course modules.
$newcoursemodules = get_coursemodules_in_course('label', $duplicated['id']);
$this->assertCount(1, $newcoursemodules);
$cm = array_pop($newcoursemodules);
// Get the comeptencies for this cm.
$newcoursemodulecomps = api::list_course_module_competencies_in_course_module($cm);
$this->assertCount(2, $newcoursemodulecomps);
// Ensure the override grade settings are restored properly.
$this->assertEquals($coursemodulecomps[0]->get('overridegrade'), $newcoursemodulecomps[0]->get('overridegrade'));
$this->assertEquals($coursemodulecomps[1]->get('overridegrade'), $newcoursemodulecomps[1]->get('overridegrade'));
}
/**
* Gets the course, user and plan competency for the given competency ID
*
* @param int $compid ID of the competency.
* @return array array containing the three related competencies
*/
private function get_related_competencies(int $compid): array {
$coursecomp = api::get_user_competency_in_course($this->course->id, $this->user->id, $compid);
$usercomp = api::get_user_competency($this->user->id, $compid);
$plancomp = api::get_plan_competency($this->plan, $compid);
return [$coursecomp, $plancomp, $usercomp];
}
}
+2 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20220825" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20221009" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
@@ -3889,6 +3889,7 @@
<FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The field used to naturally sort this link."/>
<FIELD NAME="competencyid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The course competency this activity is linked to."/>
<FIELD NAME="ruleoutcome" TYPE="int" LENGTH="2" NOTNULL="true" SEQUENCE="false" COMMENT="The outcome when an activity is completed."/>
<FIELD NAME="overridegrade" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Enables the ability to override an existing competencys grade."/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+12
View File
@@ -2925,5 +2925,17 @@ privatefiles,moodle|/user/files.php';
upgrade_main_savepoint(true, 2022092200.01);
}
if ($oldversion < 2022101400.01) {
$table = new xmldb_table('competency_modulecomp');
$field = new xmldb_field('overridegrade', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'ruleoutcome');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2022101400.01);
}
return true;
}
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2022101400.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2022101400.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.1dev+ (Build: 20221014)'; // Human-friendly version name