mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 04:52:36 +02:00
MDL-52206 completion: New criteria to handle behaviour between modules
This commit is contained in:
parent
cd52b46e89
commit
d975251813
@ -4,6 +4,15 @@ information provided here is intended especially for developers.
|
||||
=== 4.0 ===
|
||||
* New method mark_course_completions_activity_criteria() has been added to mark course completions instantly. It is
|
||||
based on cron for completion_criteria_activity.php which is refactored to use it as well.
|
||||
* Modified completion criteria to allow plugins to override core completion logic.
|
||||
* Core now passes an additional parameter to '_get_completion_state'. This is an array representation of the completion results that have already been
|
||||
tested. Currently contains - viewed, usegrade, passgrade. Any plugin that are dependent on these criteria can now check this array instead of retesting it.
|
||||
* Introduced a new plugin function - '_get_completion_aggregation_state', that would indicate the aggregation type/relationship between the plugin and core
|
||||
completion criteria. This callback should either return a COMPLETION_STANDARD_FLOW / COMPLETION_CUSTOM_MODULE_FLOW. The former for default existing core
|
||||
behaviour while the latter enforces the override logic from the plugin. Defaults to COMPLETION_STANDARD_FLOW if not defined. This is useful when plugins
|
||||
need to override the core completion criteria in cases where it may be dependent on them. In these cases, the 'source of truth' would be the response
|
||||
from the plugin's 'get_completion_state' function. e.g. Quiz's completion defines a criteria of 'requires passing grade OR all attempts AND min attempts
|
||||
reached.' In these cases, even if a passing grade has not been achieved, the activity should be marked as completed if the no.of attempts have been reached.
|
||||
|
||||
=== 3.11 ===
|
||||
* New Behat steps for activity completion in the behat_completion class:
|
||||
|
@ -132,6 +132,16 @@ define('COMPLETION_OR', false);
|
||||
*/
|
||||
define('COMPLETION_AND', true);
|
||||
|
||||
/**
|
||||
* When a module implements this, completion state is dependent to the
|
||||
* module's _get_completion_state callback and activity_custom_completion class.
|
||||
*/
|
||||
define('COMPLETION_CUSTOM_MODULE_FLOW', true);
|
||||
/**
|
||||
* Standard flow indicates ALL conditions need to be met for completion to be marked as done.
|
||||
*/
|
||||
define('COMPLETION_STANDARD_FLOW', false);
|
||||
|
||||
/**
|
||||
* Course completion criteria aggregation method.
|
||||
*/
|
||||
@ -686,11 +696,13 @@ class completion_info {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
||||
// Check viewed
|
||||
if ($cm->completionview == COMPLETION_VIEW_REQUIRED &&
|
||||
$current->viewed == COMPLETION_NOT_VIEWED) {
|
||||
|
||||
return COMPLETION_INCOMPLETE;
|
||||
$newstate = COMPLETION_COMPLETE;
|
||||
$completionstate = [];
|
||||
if ($cm->completionview == COMPLETION_VIEW_REQUIRED) {
|
||||
$newstate = ($current->viewed == COMPLETION_VIEWED ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE);
|
||||
$completionstate = [
|
||||
'viewed' => $newstate
|
||||
];
|
||||
}
|
||||
|
||||
if ($cm instanceof stdClass) {
|
||||
@ -706,33 +718,35 @@ class completion_info {
|
||||
// Make sure we're using a cm_info object.
|
||||
$cminfo = cm_info::create($cm, $userid);
|
||||
|
||||
$newstate = COMPLETION_COMPLETE;
|
||||
|
||||
// Check grade
|
||||
if (!is_null($cminfo->completiongradeitemnumber)) {
|
||||
$newstate = $this->get_grade_completion($cminfo, $userid);
|
||||
$completionstate['usegrade'] = $newstate;
|
||||
if ($cm->completionpassgrade) {
|
||||
// If we are asking to use pass grade completion but haven't set it,
|
||||
// If we are asking to use pass grade completion but haven't set it properly,
|
||||
// then default to COMPLETION_COMPLETE_PASS.
|
||||
if ($newstate == COMPLETION_COMPLETE) {
|
||||
return COMPLETION_COMPLETE_PASS;
|
||||
} else if ($newstate != COMPLETION_COMPLETE_PASS) {
|
||||
// Mark as incomplete if there is no grade provided or the grade has failed.
|
||||
$newstate = COMPLETION_COMPLETE_PASS;
|
||||
}
|
||||
|
||||
// The criteria is to mark an activity as complete if a passing grade has been achieved.
|
||||
// COMPLETION_COMPLETE_FAIL still marks the activity as completed which is incorrect.
|
||||
// Rectify this.
|
||||
if ($newstate == COMPLETION_COMPLETE_FAIL) {
|
||||
$newstate = COMPLETION_INCOMPLETE;
|
||||
}
|
||||
} else if ($newstate == COMPLETION_INCOMPLETE) {
|
||||
return COMPLETION_INCOMPLETE;
|
||||
|
||||
$completionstate['passgrade'] = $newstate;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin_supports('mod', $cminfo->modname, FEATURE_COMPLETION_HAS_RULES)) {
|
||||
$response = true;
|
||||
$cmcompletionclass = activity_custom_completion::get_cm_completion_class($cminfo->modname);
|
||||
if ($cmcompletionclass) {
|
||||
/** @var activity_custom_completion $cmcompletion */
|
||||
$cmcompletion = new $cmcompletionclass($cminfo, $userid);
|
||||
if ($cmcompletion->get_overall_completion_state() == COMPLETION_INCOMPLETE) {
|
||||
return COMPLETION_INCOMPLETE;
|
||||
}
|
||||
$response = $cmcompletion->get_overall_completion_state() != COMPLETION_INCOMPLETE;
|
||||
} else {
|
||||
// Fallback to the get_completion_state callback.
|
||||
$cmcompletionclass = "mod_{$cminfo->modname}\\completion\\custom_completion";
|
||||
@ -745,10 +759,34 @@ class completion_info {
|
||||
debugging("*_get_completion_state() callback functions such as $function have been deprecated and should no " .
|
||||
"longer be used. Please implement the custom completion class $cmcompletionclass which extends " .
|
||||
"\core_completion\activity_custom_completion.", DEBUG_DEVELOPER);
|
||||
if (!$function($this->course, $cminfo, $userid, COMPLETION_AND)) {
|
||||
return COMPLETION_INCOMPLETE;
|
||||
}
|
||||
$response = $function($this->course, $cm, $userid, COMPLETION_AND, $completionstate);
|
||||
}
|
||||
|
||||
// Get the relationship between the core_completion and plugin_completion criteria.
|
||||
$aggregationtype = COMPLETION_STANDARD_FLOW;
|
||||
if ($aggregationfn = component_callback_exists("mod_$cminfo->modname", 'get_completion_aggregation_state')) {
|
||||
$aggregationtype = $aggregationfn();
|
||||
}
|
||||
// If the module aggregates using COMPLETION_STANDARD_FLOW, it requires ALL conditions to be met.
|
||||
// If the aggregation type is COMPLETION_CUSTOM_MODULE_FLOW, completion can be overridden by the plugin.
|
||||
if (!$response && $aggregationtype == COMPLETION_STANDARD_FLOW) {
|
||||
return COMPLETION_INCOMPLETE;
|
||||
} else if ($aggregationtype == COMPLETION_CUSTOM_MODULE_FLOW) {
|
||||
return ($response ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
if ($completionstate) {
|
||||
// We have allowed the plugins to do it's thing and run their own checks.
|
||||
// We have now reached a state where we need to AND all the calculated results.
|
||||
$newstate = array_reduce($completionstate, function($carry, $value) {
|
||||
if ($carry == COMPLETION_INCOMPLETE) {
|
||||
return $carry;
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
|
||||
}, COMPLETION_COMPLETE);
|
||||
}
|
||||
|
||||
return $newstate;
|
||||
|
@ -96,6 +96,9 @@ completely removed from Moodle core too.
|
||||
fixed units), to always include a non-breaking space between the number and unit, and to use
|
||||
consistent rounding (always 1 decimal place by default).
|
||||
* The persistent method get() now returns the correct type for each property defined in the persistent class.
|
||||
* Require pass grade criteria is now part of core.
|
||||
Refer to upgrade.php to see transitioning from similar plugin criteria to core
|
||||
Refer to completion/upgrade.txt for additional information.
|
||||
|
||||
=== 3.11.2 ===
|
||||
* For security reasons, filelib has been updated so all requests now use emulated redirects.
|
||||
|
@ -1908,6 +1908,15 @@ function quiz_get_navigation_options() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the aggregation state for the module.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function quiz_get_completion_aggregation_state() {
|
||||
return COMPLETION_CUSTOM_MODULE_FLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the module has any update that affects the current user since a given time.
|
||||
*
|
||||
|
@ -1,6 +1,9 @@
|
||||
This files describes API changes in /mod/* - activity modules,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 4.0 ===
|
||||
* A new API function introduced to handle custom completion logic. Refer to completion/upgrade.txt for additional information.
|
||||
|
||||
=== 3.9 ===
|
||||
|
||||
* The callback get_shortcuts() is now deprecated. Please use get_course_content_items and get_all_content_items instead.
|
||||
|
Loading…
x
Reference in New Issue
Block a user