mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-78517 completion: Homogenize the module settings
Reuse the code between default course completion settings and activity completion form to avoid duplicating efforts and missing features, as happened with the grading forum.
This commit is contained in:
parent
e77452220b
commit
47ba5d207c
@ -53,6 +53,20 @@ class core_completion_bulkedit_form extends core_completion_edit_base_form {
|
||||
return $this->_modnames;
|
||||
}
|
||||
|
||||
/**
|
||||
* It will return the course module when $cms has only one course module; otherwise, null will be returned.
|
||||
*
|
||||
* @return \stdClass|null
|
||||
*/
|
||||
protected function get_cm(): ?\stdClass {
|
||||
if (count($this->cms) === 1) {
|
||||
return reset($this->cms)->get_course_module_record();
|
||||
}
|
||||
|
||||
// If there are multiple modules, so none will be selected.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of component-specific module form for the first selected module
|
||||
*
|
||||
@ -156,4 +170,4 @@ class core_completion_bulkedit_form extends core_completion_edit_base_form {
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Default activity completion form
|
||||
*
|
||||
* @package core_completion
|
||||
* @copyright 2017 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
/**
|
||||
* Default activity completion form
|
||||
*
|
||||
@ -121,4 +111,14 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
$this->set_data($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* There is no course module for this form, because it is used to update default completion settings. So it will
|
||||
* always return null.
|
||||
*
|
||||
* @return \stdClass|null
|
||||
*/
|
||||
protected function get_cm(): ?\stdClass {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -14,18 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Base form for changing completion rules
|
||||
*
|
||||
* @package core_completion
|
||||
* @copyright 2017 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once($CFG->libdir.'/formslib.php');
|
||||
require_once($CFG->libdir.'/completionlib.php');
|
||||
require_once($CFG->dirroot.'/course/modlib.php');
|
||||
|
||||
/**
|
||||
@ -36,6 +27,9 @@ require_once($CFG->dirroot.'/course/modlib.php');
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class core_completion_edit_base_form extends moodleform {
|
||||
|
||||
use \core_completion\form\form_trait;
|
||||
|
||||
/** @var moodleform_mod Do not use directly, call $this->get_module_form() */
|
||||
protected $_moduleform = null;
|
||||
/** @var bool */
|
||||
@ -50,6 +44,21 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
*/
|
||||
abstract protected function get_module_names();
|
||||
|
||||
/**
|
||||
* Get the module name. If the form have more than one modules, it will return the first one.
|
||||
*
|
||||
* @return string|null The module name or null if there is no modules associated to this form.
|
||||
*/
|
||||
protected function get_module_name(): ?string {
|
||||
$modnames = $this->get_module_names();
|
||||
if (empty($modnames)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$modnamekeys = array_keys($modnames);
|
||||
return reset($modnamekeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all selected modules support tracking view.
|
||||
*
|
||||
@ -90,7 +99,7 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function add_custom_completion_rules() {
|
||||
protected function add_completion_rules() {
|
||||
$modnames = array_keys($this->get_module_names());
|
||||
if (count($modnames) != 1 || !plugin_supports('mod', $modnames[0], FEATURE_COMPLETION_HAS_RULES, false)) {
|
||||
return [];
|
||||
@ -178,61 +187,12 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
$mform->addElement('hidden', 'id', $this->course->id);
|
||||
$mform->setType('id', PARAM_INT);
|
||||
|
||||
// Unlock completion automatically (this element can be used in validation).
|
||||
$mform->addElement('hidden', 'completionunlocked', 1);
|
||||
$mform->setType('completionunlocked', PARAM_INT);
|
||||
|
||||
$mform->addElement('select', 'completion', get_string('completion', 'completion'),
|
||||
array(COMPLETION_TRACKING_NONE => get_string('completion_none', 'completion'),
|
||||
COMPLETION_TRACKING_MANUAL => get_string('completion_manual', 'completion')));
|
||||
$mform->addHelpButton('completion', 'completion', 'completion');
|
||||
$mform->setDefault('completion', COMPLETION_TRACKING_NONE);
|
||||
|
||||
// Automatic completion once you view it.
|
||||
$autocompletionpossible = false;
|
||||
if ($this->support_views()) {
|
||||
$mform->addElement('advcheckbox', 'completionview', get_string('completionview', 'completion'),
|
||||
get_string('completionview_desc', 'completion'));
|
||||
$mform->disabledIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$autocompletionpossible = true;
|
||||
}
|
||||
|
||||
// Automatic completion once it's graded.
|
||||
if ($this->support_grades()) {
|
||||
$group = [];
|
||||
$group[] = $mform->createElement('advcheckbox', 'completionusegrade', get_string('completionusegrade', 'completion'),
|
||||
get_string('completionusegrade_desc', 'completion'));
|
||||
$mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion', '', true);
|
||||
|
||||
$group[] = $mform->createElement('advcheckbox', 'completionpassgrade', get_string('completionpassgrade', 'completion'),
|
||||
get_string('completionpassgrade_desc', 'completion'));
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion', '', true);
|
||||
$mform->disabledIf('completionpassgrade', 'completionusegrade', 'notchecked');
|
||||
|
||||
$mform->addGroup($group, 'completionpassgroup', get_string('completionpassgrade', 'completion'), ' ', false);
|
||||
$mform->disabledIf('completionpassgroup', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
|
||||
$autocompletionpossible = true;
|
||||
}
|
||||
|
||||
// Automatic completion according to module-specific rules.
|
||||
foreach ($this->add_custom_completion_rules() as $element) {
|
||||
$mform->disabledIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$autocompletionpossible = true;
|
||||
}
|
||||
|
||||
// Automatic option only appears if possible.
|
||||
if ($autocompletionpossible) {
|
||||
$mform->getElement('completion')->addOption(
|
||||
get_string('completion_automatic', 'completion'),
|
||||
COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
|
||||
// Completion expected at particular date? (For progress tracking).
|
||||
$mform->addElement('date_time_selector', 'completionexpected',
|
||||
get_string('completionexpected', 'completion'), ['optional' => true]);
|
||||
$mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
|
||||
$mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
|
||||
// Add the completion elements to the form.
|
||||
$this->add_completion_elements(
|
||||
$this->get_module_name(),
|
||||
$this->support_views(),
|
||||
$this->support_grades()
|
||||
);
|
||||
|
||||
if ($conflicts = $this->get_modules_with_hidden_rules()) {
|
||||
$mform->addElement('static', 'qwerty', '', get_string('hiddenrules', 'completion', join(', ', $conflicts)));
|
||||
@ -241,6 +201,13 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
$this->add_action_buttons();
|
||||
}
|
||||
|
||||
/**
|
||||
* Each module which defines definition_after_data() must call this method.
|
||||
*/
|
||||
public function definition_after_data() {
|
||||
$this->definition_after_data_completion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Form validation
|
||||
*
|
||||
@ -252,15 +219,8 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
public function validation($data, $files) {
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
// Completion: Don't let them choose automatic completion without turning
|
||||
// on some conditions.
|
||||
if (array_key_exists('completion', $data) &&
|
||||
$data['completion'] == COMPLETION_TRACKING_AUTOMATIC) {
|
||||
if (empty($data['completionview']) && empty($data['completionusegrade']) && empty($data['completionpassgrade']) &&
|
||||
!$this->completion_rule_enabled($data)) {
|
||||
$errors['completion'] = get_string('badautocompletion', 'completion');
|
||||
}
|
||||
}
|
||||
// Completion: Check completion fields don't have errors.
|
||||
$errors = array_merge($errors, $this->validate_completion($data));
|
||||
|
||||
return $errors;
|
||||
}
|
||||
@ -288,4 +248,4 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
384
completion/classes/form/form_trait.php
Normal file
384
completion/classes/form/form_trait.php
Normal file
@ -0,0 +1,384 @@
|
||||
<?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_completion\form;
|
||||
|
||||
use core_grades\component_gradeitems;
|
||||
|
||||
/**
|
||||
* Completion trait helper, with methods to add completion elements and validate them.
|
||||
*
|
||||
* @package core_completion
|
||||
* @since Moodle 4.3
|
||||
* @copyright 2023 Sara Arjona (sara@moodle.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
trait form_trait {
|
||||
|
||||
/**
|
||||
* Called during validation.
|
||||
* Override this method to indicate, based on the data, whether a custom completion rule is selected or not.
|
||||
*
|
||||
* @param array $data Input data (not yet validated)
|
||||
* @return bool True if one or more rules are enabled; false if none are.
|
||||
*/
|
||||
abstract protected function completion_rule_enabled($data);
|
||||
|
||||
/**
|
||||
* Add completion elements to the form and return the list of element ids.
|
||||
*
|
||||
* @return array Array of string IDs of added items, empty array if none
|
||||
*/
|
||||
abstract protected function add_completion_rules();
|
||||
|
||||
/**
|
||||
* Get the form associated to this class, where the completion elements will be added.
|
||||
* This method must be overriden by the class using this trait if it doesn't include a _form property.
|
||||
*
|
||||
* @return \MoodleQuickForm
|
||||
* @throws \coding_exception If the class does not have a _form property.
|
||||
*/
|
||||
protected function get_form(): \MoodleQuickForm {
|
||||
if (property_exists($this, '_form')) {
|
||||
return $this->_form;
|
||||
}
|
||||
|
||||
throw new \coding_exception('This class does not have a _form property. Please, add it or override the get_form() method.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cm (course module) associated to this class.
|
||||
* This method must be overriden by the class using this trait if it doesn't include a _cm property.
|
||||
*
|
||||
* @return \stdClass|null
|
||||
* @throws \coding_exception If the class does not have a _cm property.
|
||||
*/
|
||||
protected function get_cm(): ?\stdClass {
|
||||
if (property_exists($this, '_cm')) {
|
||||
return $this->_cm;
|
||||
}
|
||||
|
||||
throw new \coding_exception('This class does not have a _cm property. Please, add it or override the get_cm() method.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add completion elements to the form.
|
||||
*
|
||||
* @param string|null $modname The module name (for example, 'assign'). If null and form is moodleform_mod, the parameters are
|
||||
* overriden with the expected values from the form.
|
||||
* @param bool $supportviews True if the module supports views and false otherwise.
|
||||
* @param bool $supportgrades True if the module supports grades and false otherwise.
|
||||
* @param bool $rating True if the rating feature is enabled and false otherwise.
|
||||
* @param bool $defaultcompletion True if the default completion is enabled and false otherwise. To review in MDL-78531.
|
||||
* @throws \coding_exception If the form is not moodleform_mod and $modname is null.
|
||||
*/
|
||||
protected function add_completion_elements(
|
||||
string $modname = null,
|
||||
bool $supportviews = false,
|
||||
bool $supportgrades = false,
|
||||
bool $rating = false,
|
||||
bool $defaultcompletion = true
|
||||
): void {
|
||||
global $CFG;
|
||||
|
||||
$mform = $this->get_form();
|
||||
if ($modname === null) {
|
||||
if ($this instanceof \moodleform_mod) {
|
||||
// By default, all the modules can be initiatized with the same parameters.
|
||||
$modname = $this->_modname;
|
||||
$supportviews = plugin_supports('mod', $modname, FEATURE_COMPLETION_TRACKS_VIEWS, false);
|
||||
$supportgrades = plugin_supports('mod', $modname, FEATURE_GRADE_HAS_GRADE, false);
|
||||
$rating = $this->_features->rating;
|
||||
$defaultcompletion = $CFG->completiondefault && $this->_features->defaultcompletion;
|
||||
} else {
|
||||
throw new \coding_exception('You must specify the modname parameter if you are not using a moodleform_mod.');
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock button if people have completed it. The button will be removed later in definition_after_data if they haven't.
|
||||
$mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion'));
|
||||
$mform->registerNoSubmitButton('unlockcompletion');
|
||||
$mform->addElement('hidden', 'completionunlocked', 0);
|
||||
$mform->setType('completionunlocked', PARAM_INT);
|
||||
|
||||
$trackingdefault = COMPLETION_TRACKING_NONE;
|
||||
// If system and activity default completion is on, set it.
|
||||
if ($defaultcompletion) {
|
||||
$hasrules = plugin_supports('mod', $modname, FEATURE_COMPLETION_HAS_RULES, true);
|
||||
if ($hasrules || $supportviews) {
|
||||
$trackingdefault = COMPLETION_TRACKING_AUTOMATIC;
|
||||
} else {
|
||||
$trackingdefault = COMPLETION_TRACKING_MANUAL;
|
||||
}
|
||||
}
|
||||
|
||||
$mform->addElement(
|
||||
'select',
|
||||
'completion',
|
||||
get_string('completion', 'completion'),
|
||||
[
|
||||
COMPLETION_TRACKING_NONE => get_string('completion_none', 'completion'),
|
||||
COMPLETION_TRACKING_MANUAL => get_string('completion_manual', 'completion'),
|
||||
]
|
||||
);
|
||||
$mform->setDefault('completion', $trackingdefault);
|
||||
$mform->addHelpButton('completion', 'completion', 'completion');
|
||||
|
||||
// Automatic completion once you view it.
|
||||
$autocompletionpossible = false;
|
||||
if ($supportviews) {
|
||||
$mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'),
|
||||
get_string('completionview_desc', 'completion'));
|
||||
$mform->hideIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
// Check by default if automatic completion tracking is set.
|
||||
if ($trackingdefault == COMPLETION_TRACKING_AUTOMATIC) {
|
||||
$mform->setDefault('completionview', 1);
|
||||
}
|
||||
$autocompletionpossible = true;
|
||||
}
|
||||
|
||||
// If the activity supports grading, the grade elements must be added.
|
||||
if ($supportgrades) {
|
||||
$autocompletionpossible = true;
|
||||
$this->add_completiongrade_elements($modname, $rating);
|
||||
}
|
||||
|
||||
// Automatic completion according to module-specific rules.
|
||||
$customcompletionelements = $this->add_completion_rules();
|
||||
if (property_exists($this, '_customcompletionelements')) {
|
||||
$this->_customcompletionelements = $customcompletionelements;
|
||||
}
|
||||
|
||||
if ($customcompletionelements !== null) {
|
||||
foreach ($customcompletionelements as $element) {
|
||||
$mform->hideIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
$autocompletionpossible = $autocompletionpossible || count($customcompletionelements) > 0;
|
||||
}
|
||||
|
||||
// Automatic option only appears if possible.
|
||||
if ($autocompletionpossible) {
|
||||
$mform->getElement('completion')->addOption(
|
||||
get_string('completion_automatic', 'completion'),
|
||||
COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
|
||||
// Completion expected at particular date? (For progress tracking).
|
||||
$mform->addElement('date_time_selector', 'completionexpected', get_string('completionexpected', 'completion'),
|
||||
['optional' => true]);
|
||||
$mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
|
||||
$mform->hideIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add completion grade elements to the form.
|
||||
*
|
||||
* @param string $modname The name of the module (for example, 'assign').
|
||||
* @param bool $rating True if the rating feature is enabled and false otherwise.
|
||||
*/
|
||||
protected function add_completiongrade_elements(
|
||||
string $modname,
|
||||
bool $rating = false
|
||||
): void {
|
||||
$mform = $this->get_form();
|
||||
|
||||
$completionelementexists = $mform->elementExists('completion');
|
||||
$component = "mod_{$modname}";
|
||||
$itemnames = component_gradeitems::get_itemname_mapping_for_component($component);
|
||||
if (count($itemnames) === 1) {
|
||||
// Only one gradeitem in this activity.
|
||||
// We use the completionusegrade field here.
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionusegrade',
|
||||
get_string('completionusegrade', 'completion'),
|
||||
get_string('completionusegrade_desc', 'completion')
|
||||
);
|
||||
$mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion');
|
||||
|
||||
// Complete if the user has reached the pass grade.
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionpassgrade', null,
|
||||
get_string('completionpassgrade_desc', 'completion')
|
||||
);
|
||||
$mform->disabledIf('completionpassgrade', 'completionusegrade', 'notchecked');
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion');
|
||||
|
||||
if ($completionelementexists) {
|
||||
$mform->hideIf('completionpassgrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
|
||||
// The disabledIf logic differs between ratings and other grade items due to different field types.
|
||||
if ($rating) {
|
||||
// If using the rating system, there is no grade unless ratings are enabled.
|
||||
$mform->disabledIf('completionusegrade', 'assessed', 'eq', 0);
|
||||
$mform->disabledIf('completionpassgrade', 'assessed', 'eq', 0);
|
||||
} else {
|
||||
// All other field types use the '$gradefieldname' field's modgrade_type.
|
||||
$itemnumbers = array_keys($itemnames);
|
||||
$itemnumber = array_shift($itemnumbers);
|
||||
$gradefieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade');
|
||||
$mform->disabledIf('completionusegrade', "{$gradefieldname}[modgrade_type]", 'eq', 'none');
|
||||
$mform->disabledIf('completionpassgrade', "{$gradefieldname}[modgrade_type]", 'eq', 'none');
|
||||
}
|
||||
} else if (count($itemnames) > 1) {
|
||||
// There are multiple grade items in this activity.
|
||||
// Show them all.
|
||||
$options = [
|
||||
'' => get_string('activitygradenotrequired', 'completion'),
|
||||
];
|
||||
foreach ($itemnames as $itemnumber => $itemname) {
|
||||
$options[$itemnumber] = get_string("grade_{$itemname}_name", $component);
|
||||
}
|
||||
|
||||
$mform->addElement(
|
||||
'select',
|
||||
'completiongradeitemnumber',
|
||||
get_string('completionusegrade', 'completion'),
|
||||
$options
|
||||
);
|
||||
|
||||
// Complete if the user has reached the pass grade.
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionpassgrade', null,
|
||||
get_string('completionpassgrade_desc', 'completion')
|
||||
);
|
||||
$mform->disabledIf('completionpassgrade', 'completiongradeitemnumber', 'eq', '');
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion');
|
||||
|
||||
if ($completionelementexists) {
|
||||
$mform->hideIf('completiongradeitemnumber', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf('completionpassgrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some extra validation for completion settings.
|
||||
*
|
||||
* @param array $data Array of ["fieldname" => value] of submitted data.
|
||||
* @return array List of ["element_name" => "error_description"] if there are errors or an empty array if everything is OK.
|
||||
*/
|
||||
protected function validate_completion(array $data): array {
|
||||
$errors = [];
|
||||
|
||||
// Completion: Don't let them choose automatic completion without turning on some conditions.
|
||||
$automaticcompletion = array_key_exists('completion', $data) && $data['completion'] == COMPLETION_TRACKING_AUTOMATIC;
|
||||
// Ignore this check when completion settings are locked, as the options are then disabled.
|
||||
$automaticcompletion = $automaticcompletion && !empty($data['completionunlocked']);
|
||||
if ($automaticcompletion) {
|
||||
// View to complete.
|
||||
$rulesenabled = !empty($data['completionview']);
|
||||
|
||||
// Use grade to complete (only one grade item).
|
||||
$rulesenabled = $rulesenabled || !empty($data['completionusegrade']) || !empty($data['completionpassgrade']);
|
||||
|
||||
// Use grade to complete (specific grade item).
|
||||
if (!$rulesenabled && isset($data['completiongradeitemnumber'])) {
|
||||
$rulesenabled = $data['completiongradeitemnumber'] != '';
|
||||
}
|
||||
|
||||
// Module-specific completion rules.
|
||||
$rulesenabled = $rulesenabled || $this->completion_rule_enabled($data);
|
||||
|
||||
if (!$rulesenabled) {
|
||||
// No rules are enabled. Can't set automatically completed without rules.
|
||||
$errors['completion'] = get_string('badautocompletion', 'completion');
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* It should be called from the definition_after_data() to setup the completion settings in the form.
|
||||
*/
|
||||
protected function definition_after_data_completion(): void {
|
||||
global $COURSE;
|
||||
|
||||
$mform = $this->get_form();
|
||||
|
||||
$completion = new \completion_info($COURSE);
|
||||
if ($completion->is_enabled()) {
|
||||
// If anybody has completed the activity, these options will be 'locked'.
|
||||
$cm = $this->get_cm();
|
||||
$completedcount = empty($cm) ? 0 : $completion->count_user_data($cm);
|
||||
$freeze = false;
|
||||
if (!$completedcount) {
|
||||
if ($mform->elementExists('unlockcompletion')) {
|
||||
$mform->removeElement('unlockcompletion');
|
||||
}
|
||||
// Automatically set to unlocked. Note: this is necessary in order to make it recalculate completion once
|
||||
// the option is changed, maybe someone has completed it now.
|
||||
$mform->getElement('completionunlocked')->setValue(1);
|
||||
} else {
|
||||
// Has the element been unlocked, either by the button being pressed in this request, or the field already
|
||||
// being set from a previous one?
|
||||
if ($mform->exportValue('unlockcompletion') || $mform->exportValue('completionunlocked')) {
|
||||
// Yes, add in warning text and set the hidden variable.
|
||||
$completedunlockedel = $mform->createElement(
|
||||
'static',
|
||||
'completedunlocked',
|
||||
get_string('completedunlocked', 'completion'),
|
||||
get_string('completedunlockedtext', 'completion')
|
||||
);
|
||||
$mform->insertElementBefore($completedunlockedel, 'unlockcompletion');
|
||||
$mform->removeElement('unlockcompletion');
|
||||
$mform->getElement('completionunlocked')->setValue(1);
|
||||
} else {
|
||||
// No, add in the warning text with the count (now we know it) before the unlock button.
|
||||
$completedwarningel = $mform->createElement(
|
||||
'static',
|
||||
'completedwarning',
|
||||
get_string('completedwarning', 'completion'),
|
||||
get_string('completedwarningtext', 'completion', $completedcount)
|
||||
);
|
||||
$mform->insertElementBefore($completedwarningel, 'unlockcompletion');
|
||||
$freeze = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($freeze) {
|
||||
$mform->freeze('completion');
|
||||
if ($mform->elementExists('completionview')) {
|
||||
// Don't use hardFreeze or checkbox value gets lost.
|
||||
$mform->freeze('completionview');
|
||||
}
|
||||
if ($mform->elementExists('completionusegrade')) {
|
||||
$mform->freeze('completionusegrade');
|
||||
}
|
||||
if ($mform->elementExists('completionpassgrade')) {
|
||||
$mform->freeze('completionpassgrade');
|
||||
|
||||
// Has the completion pass grade completion criteria been set? If it has, then we shouldn't change
|
||||
// the gradepass field.
|
||||
if ($mform->exportValue('completionpassgrade')) {
|
||||
$mform->freeze('gradepass');
|
||||
}
|
||||
}
|
||||
if ($mform->elementExists('completiongradeitemnumber')) {
|
||||
$mform->freeze('completiongradeitemnumber');
|
||||
}
|
||||
if (property_exists($this, '_customcompletionelements')) {
|
||||
$mform->freeze($this->_customcompletionelements);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -43,8 +43,8 @@ Feature: Allow teachers to bulk edit activity completion rules in a course.
|
||||
And I click on "Edit" "button"
|
||||
And I should see "Completion tracking"
|
||||
And I should see "The changes will affect the following 2 activities or resources:"
|
||||
And I should see "Student must make a submission"
|
||||
And I select "Show activity as complete when conditions are met" from the "completion" singleselect
|
||||
And I should see "Student must make a submission"
|
||||
And I click on "completionview" "checkbox"
|
||||
And I click on "completionusegrade" "checkbox"
|
||||
And I click on "completionsubmit" "checkbox"
|
||||
@ -74,8 +74,8 @@ Feature: Allow teachers to bulk edit activity completion rules in a course.
|
||||
And I click on "Edit" "button"
|
||||
And I should see "Completion tracking"
|
||||
And I should see "The changes will affect the following 2 activities or resources:"
|
||||
And I should see "Student must make a submission"
|
||||
And I select "Show activity as complete when conditions are met" from the "completion" singleselect
|
||||
And I should see "Student must make a submission"
|
||||
And I click on "completionusegrade" "checkbox"
|
||||
And I click on "completionpassgrade" "checkbox"
|
||||
And I click on "Save changes" "button"
|
||||
|
@ -1,50 +1,152 @@
|
||||
@core @core_completion
|
||||
@core @core_completion @javascript
|
||||
Feature: Allow teachers to edit the default activity completion rules in a course.
|
||||
In order to set the activity completion defaults for new activities
|
||||
As a teacher
|
||||
I need to be able to edit the completion rules for a group of activities.
|
||||
|
||||
# Given I am a teacher in a course with completion tracking enabled and activities present.
|
||||
# When I edit activity completion defaults for activity types.
|
||||
# Then the completion rule defaults should apply only to activities created from that point onwards.
|
||||
@javascript
|
||||
Scenario: Bulk edit activity completion default rules
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
| fullname | shortname | category | enablecompletion |
|
||||
| Course 1 | C1 | 0 | 1 |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | Frist | teacher1@example.com |
|
||||
| student1 | Student | First | student1@example.com |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | grade |
|
||||
| assign | C1 | a1 | Test assignment one | Submit something! | 300 |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I set the following fields to these values:
|
||||
| Enable completion tracking | Yes |
|
||||
And I press "Save and display"
|
||||
|
||||
# Given I am a teacher in a course with completion tracking enabled and activities present.
|
||||
# When I edit activity completion defaults for activity types.
|
||||
# Then the completion rule defaults should apply only to activities created from that point onwards.
|
||||
Scenario: Edit default activity completion rules for assignment
|
||||
Given the following "activity" exists:
|
||||
| activity | assign |
|
||||
| course | C1 |
|
||||
| name | Test assignment one |
|
||||
| completion | 0 |
|
||||
And I am on the "Course 1" course page logged in as teacher1
|
||||
When I navigate to "Course completion" in current page administration
|
||||
And I set the field "Course completion tertiary navigation" to "Default activity completion"
|
||||
And I click on "Assignments" "checkbox"
|
||||
And I click on "Edit" "button"
|
||||
And I should see "Completion tracking"
|
||||
And I should see "The changes will affect the following 1 activities or resources:"
|
||||
And I should see "Student must make a submission"
|
||||
And I set the following fields to these values:
|
||||
| completion | Show activity as complete when conditions are met|
|
||||
| completionview | 1 |
|
||||
| completionusegrade | 1 |
|
||||
| completionsubmit | 1 |
|
||||
| completion | Show activity as complete when conditions are met |
|
||||
| completionview | 0 |
|
||||
| completionusegrade | 1 |
|
||||
| completionsubmit | 1 |
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "Changes saved"
|
||||
And I should see "With conditions" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
|
||||
And I should see "Student must view this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
|
||||
And I should not see "Student must view this activity to complete it" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
|
||||
And I should see "Student must receive a grade to complete this activity" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
|
||||
And I should see "Student must make a submission" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
|
||||
And I should not see "Completion expected on" in the "//div[contains(concat(' ', normalize-space(@class), ' '), ' row ')][.//*[text() = 'Assignments']]" "xpath_element"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I press "Add an activity or resource"
|
||||
And I click on "Add a new Assignment" "link" in the "Add an activity or resource" "dialogue"
|
||||
And I expand all fieldsets
|
||||
# Completion tracking 2 = Show activity as complete when conditions are met.
|
||||
And the field "Completion tracking" matches value "2"
|
||||
And the field "completionview" matches value "0"
|
||||
And the field "completionusegrade" matches value "1"
|
||||
And the field "completionsubmit" matches value "1"
|
||||
But I am on the "Test assignment one" Activity page
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I expand all fieldsets
|
||||
# Completion tracking 0 = Do not indicate activity completion.
|
||||
And the field "Completion tracking" matches value "0"
|
||||
|
||||
Scenario: Edit default activity completion rules for forum
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | C1 |
|
||||
| name | Test forum one |
|
||||
| completion | 0 |
|
||||
And I am on the "Course 1" course page logged in as teacher1
|
||||
When I navigate to "Course completion" in current page administration
|
||||
And I select "Default activity completion" from the "Course completion tertiary navigation" singleselect
|
||||
And I click on "Forums" "checkbox"
|
||||
And I click on "Edit" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion | Show activity as complete when conditions are met |
|
||||
| completionview | 0 |
|
||||
# 0 = Rating.
|
||||
| completiongradeitemnumber | 0 |
|
||||
| completionpassgrade | 1 |
|
||||
| completionpostsenabled | 1 |
|
||||
| completionposts | 2 |
|
||||
| completionrepliesenabled | 1 |
|
||||
| completionreplies | 3 |
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "Changes saved"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I press "Add an activity or resource"
|
||||
And I click on "Add a new Forum" "link" in the "Add an activity or resource" "dialogue"
|
||||
And I expand all fieldsets
|
||||
# Completion tracking 2 = Show activity as complete when conditions are met.
|
||||
And the field "Completion tracking" matches value "2"
|
||||
And the field "completionview" matches value "0"
|
||||
# Value 0 for completiongradeitemnumber is "Rating".
|
||||
And the field "completiongradeitemnumber" matches value "0"
|
||||
And the field "completionpassgrade" matches value "1"
|
||||
And the field "completionpostsenabled" matches value "1"
|
||||
And the field "completionposts" matches value "2"
|
||||
And the field "completionrepliesenabled" matches value "1"
|
||||
And the field "completionreplies" matches value "3"
|
||||
But I am on the "Test forum one" Activity page
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I expand all fieldsets
|
||||
# Completion tracking 0 = Do not indicate activity completion.
|
||||
And the field "Completion tracking" matches value "0"
|
||||
|
||||
Scenario: Edit default activity completion rules for glossary
|
||||
Given the following "activity" exists:
|
||||
| activity | glossary |
|
||||
| course | C1 |
|
||||
| name | Test glossary one |
|
||||
| completion | 0 |
|
||||
And I am on the "Course 1" course page logged in as teacher1
|
||||
When I navigate to "Course completion" in current page administration
|
||||
And I select "Default activity completion" from the "Course completion tertiary navigation" singleselect
|
||||
And I click on "Glossaries" "checkbox"
|
||||
And I click on "Edit" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion | Show activity as complete when conditions are met |
|
||||
| completionview | 0 |
|
||||
| completionusegrade | 1 |
|
||||
| completionentriesenabled | 1 |
|
||||
| completionentries | 2 |
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "Changes saved"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I press "Add an activity or resource"
|
||||
And I click on "Add a new Glossary" "link" in the "Add an activity or resource" "dialogue"
|
||||
And I expand all fieldsets
|
||||
# Completion tracking 2 = Show activity as complete when conditions are met.
|
||||
And the field "Completion tracking" matches value "2"
|
||||
And the field "completionview" matches value "0"
|
||||
And the field "completionusegrade" matches value "1"
|
||||
And the field "completionentriesenabled" matches value "1"
|
||||
And the field "completionentries" matches value "2"
|
||||
But I am on the "Test glossary one" Activity page
|
||||
And I navigate to "Settings" in current page administration
|
||||
And I expand all fieldsets
|
||||
# Completion tracking 0 = Do not indicate activity completion.
|
||||
And the field "Completion tracking" matches value "0"
|
||||
|
||||
Scenario: Edit default activity completion without rules for automatic completion
|
||||
Given I am on the "Course 1" course page logged in as teacher1
|
||||
When I navigate to "Course completion" in current page administration
|
||||
And I select "Default activity completion" from the "Course completion tertiary navigation" singleselect
|
||||
And I click on "Assignments" "checkbox"
|
||||
And I click on "Edit" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion | Show activity as complete when conditions are met |
|
||||
| completionview | 0 |
|
||||
| completionusegrade | 0 |
|
||||
| completionsubmit | 0 |
|
||||
And I click on "Save changes" "button"
|
||||
Then I should see "When you select automatic completion, you must also enable at least one requirement (below)."
|
||||
And I should not see "Changes saved"
|
||||
|
@ -1,6 +1,10 @@
|
||||
This files describes API changes in /completion/* - completion,
|
||||
This file describes API changes in /completion/* - completion,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 4.3 ===
|
||||
* A trait class, core_completion/form/form_trait has been added to reuse code for adding and validation completion settings to any
|
||||
form.
|
||||
|
||||
=== 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.
|
||||
|
@ -14,20 +14,12 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Moodleform.
|
||||
*
|
||||
* @package core_course
|
||||
* @copyright Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once($CFG->libdir.'/formslib.php');
|
||||
require_once($CFG->libdir.'/completionlib.php');
|
||||
require_once($CFG->libdir.'/gradelib.php');
|
||||
require_once($CFG->libdir.'/plagiarismlib.php');
|
||||
|
||||
use core\content\export\exporters\component_exporter;
|
||||
use core_grades\component_gradeitems;
|
||||
|
||||
/**
|
||||
@ -36,8 +28,12 @@ use core_grades\component_gradeitems;
|
||||
*
|
||||
* @package core_course
|
||||
* @copyright Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class moodleform_mod extends moodleform {
|
||||
|
||||
use \core_completion\form\form_trait;
|
||||
|
||||
/** Current data */
|
||||
protected $current;
|
||||
/**
|
||||
@ -321,71 +317,8 @@ abstract class moodleform_mod extends moodleform {
|
||||
}
|
||||
}
|
||||
|
||||
// Completion: If necessary, freeze fields
|
||||
$completion = new completion_info($COURSE);
|
||||
if ($completion->is_enabled()) {
|
||||
// If anybody has completed the activity, these options will be 'locked'
|
||||
$completedcount = empty($this->_cm)
|
||||
? 0
|
||||
: $completion->count_user_data($this->_cm);
|
||||
|
||||
$freeze = false;
|
||||
if (!$completedcount) {
|
||||
if ($mform->elementExists('unlockcompletion')) {
|
||||
$mform->removeElement('unlockcompletion');
|
||||
}
|
||||
// Automatically set to unlocked (note: this is necessary
|
||||
// in order to make it recalculate completion once the option
|
||||
// is changed, maybe someone has completed it now)
|
||||
$mform->getElement('completionunlocked')->setValue(1);
|
||||
} else {
|
||||
// Has the element been unlocked, either by the button being pressed
|
||||
// in this request, or the field already being set from a previous one?
|
||||
if ($mform->exportValue('unlockcompletion') ||
|
||||
$mform->exportValue('completionunlocked')) {
|
||||
// Yes, add in warning text and set the hidden variable
|
||||
$mform->insertElementBefore(
|
||||
$mform->createElement('static', 'completedunlocked',
|
||||
get_string('completedunlocked', 'completion'),
|
||||
get_string('completedunlockedtext', 'completion')),
|
||||
'unlockcompletion');
|
||||
$mform->removeElement('unlockcompletion');
|
||||
$mform->getElement('completionunlocked')->setValue(1);
|
||||
} else {
|
||||
// No, add in the warning text with the count (now we know
|
||||
// it) before the unlock button
|
||||
$mform->insertElementBefore(
|
||||
$mform->createElement('static', 'completedwarning',
|
||||
get_string('completedwarning', 'completion'),
|
||||
get_string('completedwarningtext', 'completion', $completedcount)),
|
||||
'unlockcompletion');
|
||||
$freeze = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($freeze) {
|
||||
$mform->freeze('completion');
|
||||
if ($mform->elementExists('completionview')) {
|
||||
$mform->freeze('completionview'); // don't use hardFreeze or checkbox value gets lost
|
||||
}
|
||||
if ($mform->elementExists('completionusegrade')) {
|
||||
$mform->freeze('completionusegrade');
|
||||
}
|
||||
if ($mform->elementExists('completionpassgrade')) {
|
||||
$mform->freeze('completionpassgrade');
|
||||
|
||||
// Has the completion pass grade completion criteria been set?
|
||||
// If it has then we shouldn't change the gradepass field.
|
||||
if ($mform->exportValue('completionpassgrade')) {
|
||||
$mform->freeze('gradepass');
|
||||
}
|
||||
}
|
||||
if ($mform->elementExists('completiongradeitemnumber')) {
|
||||
$mform->freeze('completiongradeitemnumber');
|
||||
}
|
||||
$mform->freeze($this->_customcompletionelements);
|
||||
}
|
||||
}
|
||||
// Completion: If necessary, freeze fields.
|
||||
$this->definition_after_data_completion();
|
||||
|
||||
// Freeze admin defaults if required (and not different from default)
|
||||
$this->apply_admin_locked_flags();
|
||||
@ -509,33 +442,8 @@ abstract class moodleform_mod extends moodleform {
|
||||
}
|
||||
}
|
||||
|
||||
// Completion: Don't let them choose automatic completion without turning
|
||||
// on some conditions. Ignore this check when completion settings are
|
||||
// locked, as the options are then disabled.
|
||||
$automaticcompletion = array_key_exists('completion', $data);
|
||||
$automaticcompletion = $automaticcompletion && $data['completion'] == COMPLETION_TRACKING_AUTOMATIC;
|
||||
$automaticcompletion = $automaticcompletion && !empty($data['completionunlocked']);
|
||||
|
||||
if ($automaticcompletion) {
|
||||
// View to complete.
|
||||
$rulesenabled = !empty($data['completionview']);
|
||||
|
||||
// Use grade to complete (only one grade item).
|
||||
$rulesenabled = $rulesenabled || !empty($data['completionusegrade']) || !empty($data['completionpassgrade']);
|
||||
|
||||
// Use grade to complete (specific grade item).
|
||||
if (!$rulesenabled && isset($data['completiongradeitemnumber'])) {
|
||||
$rulesenabled = $data['completiongradeitemnumber'] != '';
|
||||
}
|
||||
|
||||
// Module-specific completion rules.
|
||||
$rulesenabled = $rulesenabled || $this->completion_rule_enabled($data);
|
||||
|
||||
if (!$rulesenabled) {
|
||||
// No rules are enabled. Can't set automatically completed without rules.
|
||||
$errors['completion'] = get_string('badautocompletion', 'completion');
|
||||
}
|
||||
}
|
||||
// Completion: Check completion fields don't have errors.
|
||||
$errors = array_merge($errors, $this->validate_completion($data));
|
||||
|
||||
// Availability: Check availability field does not have errors.
|
||||
if (!empty($CFG->enableavailability)) {
|
||||
@ -730,139 +638,11 @@ abstract class moodleform_mod extends moodleform {
|
||||
if(!isset($completion)) {
|
||||
$completion = new completion_info($COURSE);
|
||||
}
|
||||
|
||||
// Add the completion tracking elements to the form.
|
||||
if ($completion->is_enabled()) {
|
||||
$mform->addElement('header', 'activitycompletionheader', get_string('activitycompletion', 'completion'));
|
||||
// Unlock button for if people have completed it (will
|
||||
// be removed in definition_after_data if they haven't)
|
||||
$mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion'));
|
||||
$mform->registerNoSubmitButton('unlockcompletion');
|
||||
$mform->addElement('hidden', 'completionunlocked', 0);
|
||||
$mform->setType('completionunlocked', PARAM_INT);
|
||||
|
||||
$trackingdefault = COMPLETION_TRACKING_NONE;
|
||||
// If system and activity default is on, set it.
|
||||
if ($CFG->completiondefault && $this->_features->defaultcompletion) {
|
||||
$hasrules = plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_HAS_RULES, true);
|
||||
$tracksviews = plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, true);
|
||||
if ($hasrules || $tracksviews) {
|
||||
$trackingdefault = COMPLETION_TRACKING_AUTOMATIC;
|
||||
} else {
|
||||
$trackingdefault = COMPLETION_TRACKING_MANUAL;
|
||||
}
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'completion', get_string('completion', 'completion'),
|
||||
array(COMPLETION_TRACKING_NONE=>get_string('completion_none', 'completion'),
|
||||
COMPLETION_TRACKING_MANUAL=>get_string('completion_manual', 'completion')));
|
||||
$mform->setDefault('completion', $trackingdefault);
|
||||
$mform->addHelpButton('completion', 'completion', 'completion');
|
||||
|
||||
// Automatic completion once you view it
|
||||
$gotcompletionoptions = false;
|
||||
if (plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) {
|
||||
$mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'),
|
||||
get_string('completionview_desc', 'completion'));
|
||||
$mform->hideIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
// Check by default if automatic completion tracking is set.
|
||||
if ($trackingdefault == COMPLETION_TRACKING_AUTOMATIC) {
|
||||
$mform->setDefault('completionview', 1);
|
||||
}
|
||||
$gotcompletionoptions = true;
|
||||
}
|
||||
|
||||
if (plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false)) {
|
||||
// This activity supports grading.
|
||||
$gotcompletionoptions = true;
|
||||
|
||||
$component = "mod_{$this->_modname}";
|
||||
$itemnames = component_gradeitems::get_itemname_mapping_for_component($component);
|
||||
|
||||
if (count($itemnames) === 1) {
|
||||
// Only one gradeitem in this activity.
|
||||
// We use the completionusegrade field here.
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionusegrade',
|
||||
get_string('completionusegrade', 'completion'),
|
||||
get_string('completionusegrade_desc', 'completion')
|
||||
);
|
||||
$mform->hideIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion');
|
||||
|
||||
// Complete if the user has reached the pass grade.
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionpassgrade', null,
|
||||
get_string('completionpassgrade_desc', 'completion')
|
||||
);
|
||||
$mform->hideIf('completionpassgrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->disabledIf('completionpassgrade', 'completionusegrade', 'notchecked');
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion');
|
||||
|
||||
// The disabledIf logic differs between ratings and other grade items due to different field types.
|
||||
if ($this->_features->rating) {
|
||||
// If using the rating system, there is no grade unless ratings are enabled.
|
||||
$mform->disabledIf('completionusegrade', 'assessed', 'eq', 0);
|
||||
$mform->disabledIf('completionpassgrade', 'assessed', 'eq', 0);
|
||||
} else {
|
||||
// All other field types use the '$gradefieldname' field's modgrade_type.
|
||||
$itemnumbers = array_keys($itemnames);
|
||||
$itemnumber = array_shift($itemnumbers);
|
||||
$gradefieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade');
|
||||
$mform->disabledIf('completionusegrade', "{$gradefieldname}[modgrade_type]", 'eq', 'none');
|
||||
$mform->disabledIf('completionpassgrade', "{$gradefieldname}[modgrade_type]", 'eq', 'none');
|
||||
}
|
||||
} else if (count($itemnames) > 1) {
|
||||
// There are multiple grade items in this activity.
|
||||
// Show them all.
|
||||
$options = [
|
||||
'' => get_string('activitygradenotrequired', 'completion'),
|
||||
];
|
||||
foreach ($itemnames as $itemnumber => $itemname) {
|
||||
$options[$itemnumber] = get_string("grade_{$itemname}_name", $component);
|
||||
}
|
||||
|
||||
$mform->addElement(
|
||||
'select',
|
||||
'completiongradeitemnumber',
|
||||
get_string('completionusegrade', 'completion'),
|
||||
$options
|
||||
);
|
||||
$mform->hideIf('completiongradeitemnumber', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
|
||||
// Complete if the user has reached the pass grade.
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionpassgrade', null,
|
||||
get_string('completionpassgrade_desc', 'completion')
|
||||
);
|
||||
$mform->hideIf('completionpassgrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->disabledIf('completionpassgrade', 'completiongradeitemnumber', 'eq', '');
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion');
|
||||
}
|
||||
}
|
||||
|
||||
// Automatic completion according to module-specific rules
|
||||
$this->_customcompletionelements = $this->add_completion_rules();
|
||||
foreach ($this->_customcompletionelements as $element) {
|
||||
$mform->hideIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
|
||||
$gotcompletionoptions = $gotcompletionoptions ||
|
||||
count($this->_customcompletionelements)>0;
|
||||
|
||||
// Automatic option only appears if possible
|
||||
if ($gotcompletionoptions) {
|
||||
$mform->getElement('completion')->addOption(
|
||||
get_string('completion_automatic', 'completion'),
|
||||
COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
|
||||
// Completion expected at particular date? (For progress tracking)
|
||||
$mform->addElement('date_time_selector', 'completionexpected', get_string('completionexpected', 'completion'),
|
||||
array('optional' => true));
|
||||
$mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
|
||||
$mform->hideIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
|
||||
$this->add_completion_elements();
|
||||
}
|
||||
|
||||
// Populate module tags.
|
||||
|
Loading…
x
Reference in New Issue
Block a user