Merge branch 'MDL-78528-master' of https://github.com/sarjona/moodle
This commit is contained in:
@@ -27,6 +27,25 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
/** @var array */
|
||||
protected $_modnames;
|
||||
|
||||
public function __construct(
|
||||
$action = null,
|
||||
$customdata = null,
|
||||
$method = 'post',
|
||||
$target = '',
|
||||
$attributes = null,
|
||||
$editable = true,
|
||||
$ajaxformdata = null
|
||||
) {
|
||||
$this->modules = $customdata['modules'];
|
||||
if ($modname = $this->get_module_name()) {
|
||||
// Set the form suffix to the module name so that the form identifier is unique for each module type.
|
||||
$this->set_suffix('_' . $modname);
|
||||
}
|
||||
|
||||
parent::__construct($action, $customdata, $method, $target, $attributes, $editable, $ajaxformdata);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns list of types of selected modules
|
||||
*
|
||||
@@ -66,7 +85,7 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
throw new \moodle_exception('noformdesc');
|
||||
}
|
||||
|
||||
list($module, $context, $cw, $cmrec, $data) = prepare_new_moduleinfo_data($course, $modname, 0);
|
||||
list($module, $context, $cw, $cmrec, $data) = prepare_new_moduleinfo_data($course, $modname, 0, $this->get_suffix());
|
||||
$data->return = 0;
|
||||
$data->sr = 0;
|
||||
$data->add = $modname;
|
||||
@@ -75,6 +94,7 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
$mformclassname = 'mod_'.$modname.'_mod_form';
|
||||
$PAGE->start_collecting_javascript_requirements();
|
||||
$this->_moduleform = new $mformclassname($data, 0, $cmrec, $course);
|
||||
$this->_moduleform->set_suffix('_' . $modname);
|
||||
$PAGE->end_collecting_javascript_requirements();
|
||||
|
||||
return $this->_moduleform;
|
||||
@@ -101,7 +121,12 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
$modnames = array_keys($this->get_module_names());
|
||||
$modname = $modnames[0];
|
||||
// Pre-fill the form with the current completion rules of the first selected module type.
|
||||
list($module, $context, $cw, $cmrec, $data) = prepare_new_moduleinfo_data($this->course, $modname, 0);
|
||||
list($module, $context, $cw, $cmrec, $data) = prepare_new_moduleinfo_data(
|
||||
$this->course,
|
||||
$modname,
|
||||
0,
|
||||
$this->get_suffix()
|
||||
);
|
||||
$data = (array)$data;
|
||||
$modform->data_preprocessing($data);
|
||||
// Unset fields that will conflict with this form and set data to this form.
|
||||
@@ -121,4 +146,12 @@ class core_completion_defaultedit_form extends core_completion_edit_base_form {
|
||||
protected function get_cm(): ?\stdClass {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method has been overridden because the form identifier must be unique for each module type.
|
||||
* Otherwise, the form will display the same data for each module type once it's submitted.
|
||||
*/
|
||||
protected function get_form_identifier() {
|
||||
return parent::get_form_identifier() . $this->get_suffix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,19 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
$moduleform->_form = $this->_form;
|
||||
if ($customcompletionelements = $moduleform->add_completion_rules()) {
|
||||
$this->hascustomrules = true;
|
||||
foreach ($customcompletionelements as $customcompletionelement) {
|
||||
// Instead of checking for the suffix at the end of the element name, we need to check for its presence
|
||||
// because some modules, like SCORM, are adding things at the end.
|
||||
if (!str_contains($customcompletionelement, $this->get_suffix())) {
|
||||
debugging(
|
||||
'Custom completion rule ' . $customcompletionelement . ' of module ' . $modnames[0] .
|
||||
' has wrong suffix and has been removed from the form. This has to be fixed by the developer',
|
||||
DEBUG_DEVELOPER
|
||||
);
|
||||
$moduleform->_form->removeElement($customcompletionelement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $customcompletionelements;
|
||||
} catch (Exception $e) {
|
||||
@@ -198,7 +211,9 @@ abstract class core_completion_edit_base_form extends moodleform {
|
||||
$mform->addElement('static', 'qwerty', '', get_string('hiddenrules', 'completion', join(', ', $conflicts)));
|
||||
}
|
||||
|
||||
$this->add_action_buttons();
|
||||
// Whether to show the cancel button or not in the form.
|
||||
$displaycancel = $this->_customdata['displaycancel'] ?? true;
|
||||
$this->add_action_buttons($displaycancel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,9 @@ use core_grades\component_gradeitems;
|
||||
*/
|
||||
trait form_trait {
|
||||
|
||||
/** @var string The suffix to be added to the completion elements when creating them (for example, 'completion_assign'). */
|
||||
protected $suffix = '';
|
||||
|
||||
/**
|
||||
* Called during validation.
|
||||
* Override this method to indicate, based on the data, whether a custom completion rule is selected or not.
|
||||
@@ -59,6 +62,24 @@ trait form_trait {
|
||||
throw new \coding_exception('This class does not have a _form property. Please, add it or override the get_form() method.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the suffix to be added to the completion elements when creating them (for example, 'completion_assign').
|
||||
*
|
||||
* @param string $suffix
|
||||
*/
|
||||
public function set_suffix(string $suffix): void {
|
||||
$this->suffix = $suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the suffix to be added to the completion elements when creating them (for example, 'completion_assign').
|
||||
*
|
||||
* @return string The suffix
|
||||
*/
|
||||
public function get_suffix(): string {
|
||||
return $this->suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -109,6 +130,7 @@ trait form_trait {
|
||||
}
|
||||
|
||||
// Unlock button if people have completed it. The button will be removed later in definition_after_data if they haven't.
|
||||
// The unlock buttons don't need suffix because they are only displayed in the module settings page.
|
||||
$mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion'));
|
||||
$mform->registerNoSubmitButton('unlockcompletion');
|
||||
$mform->addElement('hidden', 'completionunlocked', 0);
|
||||
@@ -125,27 +147,32 @@ trait form_trait {
|
||||
}
|
||||
}
|
||||
|
||||
// Get the sufix to add to the completion elements name.
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
$completionel = 'completion' . $suffix;
|
||||
$mform->addElement(
|
||||
'select',
|
||||
'completion',
|
||||
$completionel,
|
||||
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');
|
||||
$mform->setDefault($completionel, $trackingdefault);
|
||||
$mform->addHelpButton($completionel, 'completion', 'completion');
|
||||
|
||||
// Automatic completion once you view it.
|
||||
$autocompletionpossible = false;
|
||||
if ($supportviews) {
|
||||
$mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'),
|
||||
$completionviewel = 'completionview' . $suffix;
|
||||
$mform->addElement('checkbox', $completionviewel, get_string('completionview', 'completion'),
|
||||
get_string('completionview_desc', 'completion'));
|
||||
$mform->hideIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf($completionviewel, $completionel, 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
// Check by default if automatic completion tracking is set.
|
||||
if ($trackingdefault == COMPLETION_TRACKING_AUTOMATIC) {
|
||||
$mform->setDefault('completionview', 1);
|
||||
$mform->setDefault($completionviewel, 1);
|
||||
}
|
||||
$autocompletionpossible = true;
|
||||
}
|
||||
@@ -164,23 +191,24 @@ trait form_trait {
|
||||
|
||||
if ($customcompletionelements !== null) {
|
||||
foreach ($customcompletionelements as $element) {
|
||||
$mform->hideIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf($element, $completionel, 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
$autocompletionpossible = $autocompletionpossible || count($customcompletionelements) > 0;
|
||||
}
|
||||
|
||||
// Automatic option only appears if possible.
|
||||
if ($autocompletionpossible) {
|
||||
$mform->getElement('completion')->addOption(
|
||||
$mform->getElement($completionel)->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'),
|
||||
$completionexpectedel = 'completionexpected' . $suffix;
|
||||
$mform->addElement('date_time_selector', $completionexpectedel, get_string('completionexpected', 'completion'),
|
||||
['optional' => true]);
|
||||
$mform->addHelpButton('completionexpected', 'completionexpected', 'completion');
|
||||
$mform->hideIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE);
|
||||
$mform->addHelpButton($completionexpectedel, 'completionexpected', 'completion');
|
||||
$mform->hideIf($completionexpectedel, $completionel, 'eq', COMPLETION_TRACKING_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,46 +223,52 @@ trait form_trait {
|
||||
): void {
|
||||
$mform = $this->get_form();
|
||||
|
||||
$completionelementexists = $mform->elementExists('completion');
|
||||
// Get the sufix to add to the completion elements name.
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
$completionel = 'completion' . $suffix;
|
||||
$completionelementexists = $mform->elementExists($completionel);
|
||||
$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.
|
||||
$completionusegradeel = 'completionusegrade' . $suffix;
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionusegrade',
|
||||
$completionusegradeel,
|
||||
get_string('completionusegrade', 'completion'),
|
||||
get_string('completionusegrade_desc', 'completion')
|
||||
);
|
||||
$mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion');
|
||||
$mform->addHelpButton($completionusegradeel, 'completionusegrade', 'completion');
|
||||
|
||||
// Complete if the user has reached the pass grade.
|
||||
$completionpassgradeel = 'completionpassgrade' . $suffix;
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionpassgrade', null,
|
||||
$completionpassgradeel, null,
|
||||
get_string('completionpassgrade_desc', 'completion')
|
||||
);
|
||||
$mform->disabledIf('completionpassgrade', 'completionusegrade', 'notchecked');
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion');
|
||||
$mform->disabledIf($completionpassgradeel, $completionusegradeel, 'notchecked');
|
||||
$mform->addHelpButton($completionpassgradeel, 'completionpassgrade', 'completion');
|
||||
|
||||
if ($completionelementexists) {
|
||||
$mform->hideIf('completionpassgrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf($completionpassgradeel, $completionel, 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf($completionusegradeel, $completionel, '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);
|
||||
$mform->disabledIf($completionusegradeel, 'assessed', 'eq', 0);
|
||||
$mform->disabledIf($completionusegradeel, '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');
|
||||
$mform->disabledIf($completionusegradeel, "{$gradefieldname}[modgrade_type]", 'eq', 'none');
|
||||
$mform->disabledIf($completionusegradeel, "{$gradefieldname}[modgrade_type]", 'eq', 'none');
|
||||
}
|
||||
} else if (count($itemnames) > 1) {
|
||||
// There are multiple grade items in this activity.
|
||||
@@ -246,25 +280,27 @@ trait form_trait {
|
||||
$options[$itemnumber] = get_string("grade_{$itemname}_name", $component);
|
||||
}
|
||||
|
||||
$completiongradeitemnumberel = 'completiongradeitemnumber' . $suffix;
|
||||
$mform->addElement(
|
||||
'select',
|
||||
'completiongradeitemnumber',
|
||||
$completiongradeitemnumberel,
|
||||
get_string('completionusegrade', 'completion'),
|
||||
$options
|
||||
);
|
||||
|
||||
// Complete if the user has reached the pass grade.
|
||||
$completionpassgradeel = 'completionpassgrade' . $suffix;
|
||||
$mform->addElement(
|
||||
'checkbox',
|
||||
'completionpassgrade', null,
|
||||
$completionpassgradeel, null,
|
||||
get_string('completionpassgrade_desc', 'completion')
|
||||
);
|
||||
$mform->disabledIf('completionpassgrade', 'completiongradeitemnumber', 'eq', '');
|
||||
$mform->addHelpButton('completionpassgrade', 'completionpassgrade', 'completion');
|
||||
$mform->disabledIf($completionpassgradeel, $completiongradeitemnumberel, 'eq', '');
|
||||
$mform->addHelpButton($completionpassgradeel, 'completionpassgrade', 'completion');
|
||||
|
||||
if ($completionelementexists) {
|
||||
$mform->hideIf('completiongradeitemnumber', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf('completionpassgrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf($completiongradeitemnumberel, $completionel, 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
$mform->hideIf($completionpassgradeel, $completionel, 'ne', COMPLETION_TRACKING_AUTOMATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,20 +314,29 @@ trait form_trait {
|
||||
protected function validate_completion(array $data): array {
|
||||
$errors = [];
|
||||
|
||||
// Get the sufix to add to the completion elements name.
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
$completionel = 'completion' . $suffix;
|
||||
// Completion: Don't let them choose automatic completion without turning on some conditions.
|
||||
$automaticcompletion = array_key_exists('completion', $data) && $data['completion'] == COMPLETION_TRACKING_AUTOMATIC;
|
||||
$automaticcompletion = array_key_exists($completionel, $data) && $data[$completionel] == COMPLETION_TRACKING_AUTOMATIC;
|
||||
// Ignore this check when completion settings are locked, as the options are then disabled.
|
||||
// The unlock buttons don't need suffix because they are only displayed in the module settings page.
|
||||
$automaticcompletion = $automaticcompletion && !empty($data['completionunlocked']);
|
||||
if ($automaticcompletion) {
|
||||
// View to complete.
|
||||
$rulesenabled = !empty($data['completionview']);
|
||||
$completionviewel = 'completionview' . $suffix;
|
||||
$rulesenabled = !empty($data[$completionviewel]);
|
||||
|
||||
// Use grade to complete (only one grade item).
|
||||
$rulesenabled = $rulesenabled || !empty($data['completionusegrade']) || !empty($data['completionpassgrade']);
|
||||
$completionusegradeel = 'completionusegrade' . $suffix;
|
||||
$completionpassgradeel = 'completionpassgrade' . $suffix;
|
||||
$rulesenabled = $rulesenabled || !empty($data[$completionusegradeel]) || !empty($data[$completionpassgradeel]);
|
||||
|
||||
// Use grade to complete (specific grade item).
|
||||
if (!$rulesenabled && isset($data['completiongradeitemnumber'])) {
|
||||
$rulesenabled = $data['completiongradeitemnumber'] != '';
|
||||
$completiongradeitemnumberel = 'completiongradeitemnumber' . $suffix;
|
||||
if (!$rulesenabled && isset($data[$completiongradeitemnumberel])) {
|
||||
$rulesenabled = $data[$completiongradeitemnumberel] != '';
|
||||
}
|
||||
|
||||
// Module-specific completion rules.
|
||||
@@ -299,7 +344,7 @@ trait form_trait {
|
||||
|
||||
if (!$rulesenabled) {
|
||||
// No rules are enabled. Can't set automatically completed without rules.
|
||||
$errors['completion'] = get_string('badautocompletion', 'completion');
|
||||
$errors[$completionel] = get_string('badautocompletion', 'completion');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,16 +356,18 @@ trait form_trait {
|
||||
*/
|
||||
protected function definition_after_data_completion(): void {
|
||||
global $COURSE;
|
||||
|
||||
$mform = $this->get_form();
|
||||
|
||||
$completion = new \completion_info($COURSE);
|
||||
if ($completion->is_enabled()) {
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
// 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) {
|
||||
// The unlock buttons don't need suffix because they are only displayed in the module settings page.
|
||||
if ($mform->elementExists('unlockcompletion')) {
|
||||
$mform->removeElement('unlockcompletion');
|
||||
}
|
||||
@@ -355,25 +402,30 @@ trait form_trait {
|
||||
}
|
||||
|
||||
if ($freeze) {
|
||||
$mform->freeze('completion');
|
||||
if ($mform->elementExists('completionview')) {
|
||||
$completionel = 'completion' . $suffix;
|
||||
$mform->freeze($completionel);
|
||||
$completionviewel = 'completionview' . $suffix;
|
||||
if ($mform->elementExists($completionviewel)) {
|
||||
// Don't use hardFreeze or checkbox value gets lost.
|
||||
$mform->freeze('completionview');
|
||||
$mform->freeze($completionviewel);
|
||||
}
|
||||
if ($mform->elementExists('completionusegrade')) {
|
||||
$mform->freeze('completionusegrade');
|
||||
$completionusegradeel = 'completionusegrade' . $suffix;
|
||||
if ($mform->elementExists($completionusegradeel)) {
|
||||
$mform->freeze($completionusegradeel);
|
||||
}
|
||||
if ($mform->elementExists('completionpassgrade')) {
|
||||
$mform->freeze('completionpassgrade');
|
||||
$completionpassgradeel = 'completionpassgrade' . $suffix;
|
||||
if ($mform->elementExists($completionpassgradeel)) {
|
||||
$mform->freeze($completionpassgradeel);
|
||||
|
||||
// Has the completion pass grade completion criteria been set? If it has, then we shouldn't change
|
||||
// the gradepass field.
|
||||
if ($mform->exportValue('completionpassgrade')) {
|
||||
if ($mform->exportValue($completionpassgradeel)) {
|
||||
$mform->freeze('gradepass');
|
||||
}
|
||||
}
|
||||
if ($mform->elementExists('completiongradeitemnumber')) {
|
||||
$mform->freeze('completiongradeitemnumber');
|
||||
$completiongradeitemnumberel = 'completiongradeitemnumber' . $suffix;
|
||||
if ($mform->elementExists($completiongradeitemnumberel)) {
|
||||
$mform->freeze($completiongradeitemnumberel);
|
||||
}
|
||||
if (property_exists($this, '_customcompletionelements')) {
|
||||
$mform->freeze($this->_customcompletionelements);
|
||||
|
||||
@@ -205,9 +205,10 @@ class manager {
|
||||
/**
|
||||
* Gets the course modules for the current course.
|
||||
*
|
||||
* @param bool $includedefaults Whether the default values should be included or not.
|
||||
* @return stdClass $data containing the modules
|
||||
*/
|
||||
public function get_activities_and_resources() {
|
||||
public function get_activities_and_resources(bool $includedefaults = true) {
|
||||
global $DB, $OUTPUT, $CFG;
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
|
||||
@@ -224,12 +225,14 @@ class manager {
|
||||
$course = get_course($this->courseid);
|
||||
foreach ($data->modules as $module) {
|
||||
$module->icon = $OUTPUT->image_url('monologo', $module->name)->out();
|
||||
$module->formattedname = format_string(get_string('modulenameplural', 'mod_' . $module->name),
|
||||
$module->formattedname = format_string(get_string('modulename', 'mod_' . $module->name),
|
||||
true, ['context' => $coursecontext]);
|
||||
$module->canmanage = $canmanage && course_allowed_module($course, $module->name);
|
||||
$defaults = self::get_default_completion($course, $module, false);
|
||||
$defaults->modname = $module->name;
|
||||
$module->completionstatus = $this->get_completion_detail($defaults);
|
||||
if ($includedefaults) {
|
||||
$defaults = self::get_default_completion($course, $module, false);
|
||||
$defaults->modname = $module->name;
|
||||
$module->completionstatus = $this->get_completion_detail($defaults);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -443,10 +446,36 @@ class manager {
|
||||
* @param stdClass $data data received from the core_completion_bulkedit_form
|
||||
* @param bool $updatecustomrules if we need to update the custom rules of the module -
|
||||
* if no module-specific completion rules were added to the form, update of the module table is not needed.
|
||||
* @param string $suffix the suffix to add to the name of the completion rules.
|
||||
*/
|
||||
public function apply_default_completion($data, $updatecustomrules) {
|
||||
public function apply_default_completion($data, $updatecustomrules, string $suffix = '') {
|
||||
global $DB;
|
||||
|
||||
if (!empty($suffix)) {
|
||||
// Fields were renamed to avoid conflicts, but they need to be stored in DB with the original name.
|
||||
$modules = property_exists($data, 'modules') ? $data->modules : null;
|
||||
if ($modules !== null) {
|
||||
unset($data->modules);
|
||||
$data = (array)$data;
|
||||
foreach ($data as $name => $value) {
|
||||
if (str_ends_with($name, $suffix)) {
|
||||
$data[substr($name, 0, strpos($name, $suffix))] = $value;
|
||||
unset($data[$name]);
|
||||
} else if ($name == 'customdata') {
|
||||
$customrules = $value['customcompletionrules'];
|
||||
foreach ($customrules as $rulename => $rulevalue) {
|
||||
if (str_ends_with($rulename, $suffix)) {
|
||||
$customrules[substr($rulename, 0, strpos($rulename, $suffix))] = $rulevalue;
|
||||
unset($customrules[$rulename]);
|
||||
}
|
||||
}
|
||||
$data['customdata'] = $customrules;
|
||||
}
|
||||
}
|
||||
$data = (object)$data;
|
||||
}
|
||||
}
|
||||
|
||||
$courseid = $data->id;
|
||||
// MDL-72375 Unset the id here, it should not be stored in customrules.
|
||||
unset($data->id);
|
||||
@@ -511,9 +540,10 @@ class manager {
|
||||
* @param stdClass $module
|
||||
* @param bool $flatten if true all module custom completion rules become properties of the same object,
|
||||
* otherwise they can be found as array in ->customdata['customcompletionrules']
|
||||
* @param string $suffix the suffix to add to the name of the completion rules.
|
||||
* @return stdClass
|
||||
*/
|
||||
public static function get_default_completion($course, $module, $flatten = true) {
|
||||
public static function get_default_completion($course, $module, $flatten = true, string $suffix = '') {
|
||||
global $DB, $CFG;
|
||||
if ($data = $DB->get_record('course_completion_defaults', ['course' => $course->id, 'module' => $module->id],
|
||||
'completion, completionview, completionexpected, completionusegrade, completionpassgrade, customrules')) {
|
||||
@@ -541,6 +571,28 @@ class manager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the suffix is not empty, the completion rules need to be renamed to avoid conflicts.
|
||||
if (!empty($suffix)) {
|
||||
$data = (array)$data;
|
||||
foreach ($data as $name => $value) {
|
||||
if (str_starts_with($name, 'completion')) {
|
||||
$data[$name . $suffix] = $value;
|
||||
unset($data[$name]);
|
||||
} else if ($name == 'customdata') {
|
||||
$customrules = $value['customcompletionrules'];
|
||||
foreach ($customrules as $rulename => $rulevalue) {
|
||||
if (str_starts_with($rulename, 'completion')) {
|
||||
$customrules[$rulename . $suffix] = $rulevalue;
|
||||
unset($customrules[$rulename]);
|
||||
}
|
||||
}
|
||||
$data['customdata'] = $customrules;
|
||||
}
|
||||
}
|
||||
$data = (object)$data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,22 +27,15 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
|
||||
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 click on "Expand Assignment" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion | Show activity as complete when conditions are met |
|
||||
| completionview | 0 |
|
||||
| completionusegrade | 1 |
|
||||
| completionsubmit | 1 |
|
||||
And I click on "Save changes" "button"
|
||||
| completion_assign | Show activity as complete when conditions are met |
|
||||
| completionview_assign | 0 |
|
||||
| completionusegrade_assign | 1 |
|
||||
| completionsubmit_assign | 1 |
|
||||
And I should not see "Cancel" in the "[data-region='activitycompletion-forum']" "css_element"
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-assign']" "css_element"
|
||||
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 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"
|
||||
@@ -66,20 +59,19 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
|
||||
| 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 field "Course completion tertiary navigation" to "Default activity completion"
|
||||
And I click on "Expand Forum" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion | Show activity as complete when conditions are met |
|
||||
| completionview | 0 |
|
||||
| completion_forum | Show activity as complete when conditions are met |
|
||||
| completionview_forum | 0 |
|
||||
# 0 = Rating.
|
||||
| completiongradeitemnumber | 0 |
|
||||
| completionpassgrade | 1 |
|
||||
| completionpostsenabled | 1 |
|
||||
| completionposts | 2 |
|
||||
| completionrepliesenabled | 1 |
|
||||
| completionreplies | 3 |
|
||||
And I click on "Save changes" "button"
|
||||
| completiongradeitemnumber_forum | 0 |
|
||||
| completionpassgrade_forum | 1 |
|
||||
| completionpostsenabled_forum | 1 |
|
||||
| completionposts_forum | 2 |
|
||||
| completionrepliesenabled_forum | 1 |
|
||||
| completionreplies_forum | 3 |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-forum']" "css_element"
|
||||
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"
|
||||
@@ -109,16 +101,15 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
|
||||
| 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 field "Course completion tertiary navigation" to "Default activity completion"
|
||||
And I click on "Expand Glossary" "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"
|
||||
| completion_glossary | Show activity as complete when conditions are met |
|
||||
| completionview_glossary | 0 |
|
||||
| completionusegrade_glossary | 1 |
|
||||
| completionentriesenabled_glossary | 1 |
|
||||
| completionentries_glossary | 2 |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-glossary']" "css_element"
|
||||
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"
|
||||
@@ -136,17 +127,83 @@ Feature: Allow teachers to edit the default activity completion rules in a cours
|
||||
# Completion tracking 0 = Do not indicate activity completion.
|
||||
And the field "Completion tracking" matches value "0"
|
||||
|
||||
Scenario: Edit default activity completion rules for several activities
|
||||
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 set the field "Course completion tertiary navigation" to "Default activity completion"
|
||||
And I click on "Expand Assignment" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion_assign | Show activity as complete when conditions are met |
|
||||
| completionview_assign | 0 |
|
||||
| completionusegrade_assign | 0 |
|
||||
| completionsubmit_assign | 1 |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-assign']" "css_element"
|
||||
And I should see "Changes saved"
|
||||
And I click on "Expand Forum" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion_forum | Show activity as complete when conditions are met |
|
||||
| completionview_forum | 0 |
|
||||
| completionpostsenabled_forum | 1 |
|
||||
| completionposts_forum | 3 |
|
||||
| completiondiscussionsenabled_forum | 0 |
|
||||
| completionrepliesenabled_forum | 0 |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-forum']" "css_element"
|
||||
And I should see "Changes saved"
|
||||
And I click on "Expand SCORM package" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion_scorm | Show activity as complete when conditions are met |
|
||||
| completionview_scorm | 0 |
|
||||
| completionscorerequired_scorm | 3 |
|
||||
| completionstatusrequired_scorm[2] | 1 |
|
||||
| completionstatusrequired_scorm[4] | 0 |
|
||||
| completionstatusallscos_scorm | 1 |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-scorm']" "css_element"
|
||||
And I should see "Changes saved"
|
||||
And I click on "Expand Book" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion_book | Do not indicate activity completion |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-book']" "css_element"
|
||||
And I should see "Changes saved"
|
||||
And I click on "Expand Chat" "button"
|
||||
And I set the following fields to these values:
|
||||
| completion_chat | Students can manually mark the activity as completed |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-chat']" "css_element"
|
||||
And I should see "Changes saved"
|
||||
# Change current page and go back to "Default activity completion", to confirm the form values have been saved properly.
|
||||
And I set the field "Course completion tertiary navigation" to "Course completion settings"
|
||||
And I set the field "Course completion tertiary navigation" to "Default activity completion"
|
||||
Then the field "completion_chat" matches value "1"
|
||||
# Check that the rules for book, assignment and forum are still the same.
|
||||
And I click on "Expand Book" "button"
|
||||
And the field "completion_book" matches value "0"
|
||||
And I click on "Expand Assignment" "button"
|
||||
And the field "completion_assign" matches value "2"
|
||||
And the field "completionview_assign" matches value "0"
|
||||
And the field "completionusegrade_assign" matches value "0"
|
||||
And the field "completionsubmit_assign" matches value "1"
|
||||
And the field "completion_forum" matches value "2"
|
||||
And the field "completionview_forum" matches value "0"
|
||||
And the field "completionpostsenabled_forum" matches value "1"
|
||||
And the field "completionposts_forum" matches value "3"
|
||||
And the field "completiondiscussionsenabled_forum" matches value "0"
|
||||
And the field "completionrepliesenabled_forum" matches value "0"
|
||||
And the field "completion_scorm" matches value "2"
|
||||
And the field "completionview_scorm" matches value "0"
|
||||
And the field "completionscorerequired_scorm" matches value "3"
|
||||
And the field "completionstatusrequired_scorm[2]" matches value "1"
|
||||
And the field "completionstatusrequired_scorm[4]" matches value "0"
|
||||
And the field "completionstatusallscos_scorm" matches value "1"
|
||||
|
||||
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 field "Course completion tertiary navigation" to "Default activity completion"
|
||||
And I click on "Expand Assignment" "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"
|
||||
| completion_assign | Show activity as complete when conditions are met |
|
||||
| completionview_assign | 0 |
|
||||
| completionusegrade_assign | 0 |
|
||||
| completionsubmit_assign | 0 |
|
||||
And I click on "Save changes" "button" in the "[data-region='activitycompletion-assign']" "css_element"
|
||||
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"
|
||||
|
||||
@@ -5,6 +5,12 @@ information provided here is intended especially for developers.
|
||||
* A trait class, core_completion/form/form_trait has been added to reuse code for adding and validation completion settings to any
|
||||
form.
|
||||
* New method is_manual() has been added to `core_completion/cm_completion_details`
|
||||
* The method manager::get_activities_and_resources() now has the optional $includedefaults parameter to define whether the default
|
||||
values should be included or not.
|
||||
* The methods manager::apply_default_completion() and manager::get_default_completion() now have the optional $suffix parameter
|
||||
to be added to the name of the completion rules.
|
||||
* The method manager::defaultcompletion() now has the $modules and $form parameters, to specify the modules that have been set
|
||||
through the form and the current form that has been sent.
|
||||
|
||||
=== 4.0 ===
|
||||
* New method mark_course_completions_activity_criteria() has been added to mark course completions instantly. It is
|
||||
|
||||
@@ -69,10 +69,33 @@ class core_course_bulk_activity_completion_renderer extends plugin_renderer_base
|
||||
/**
|
||||
* Render the default completion tab.
|
||||
*
|
||||
* @param Array|stdClass $data the context data to pass to the template.
|
||||
* @param array|stdClass $data the context data to pass to the template.
|
||||
* @param array $modules The modules that have been sent through the form.
|
||||
* @param moodleform $form The current form that has been sent.
|
||||
* @return bool|string
|
||||
*/
|
||||
public function defaultcompletion($data) {
|
||||
public function defaultcompletion($data, $modules, $form) {
|
||||
$course = get_course($data->courseid);
|
||||
foreach ($data->modules as $module) {
|
||||
// If the user can manage this module, then the activity completion form needs to be returned too, without the
|
||||
// cancel button (so only "Save changes" button is displayed).
|
||||
if ($module->canmanage) {
|
||||
// Only create the form if it's different from the one that has been sent.
|
||||
$modform = $form;
|
||||
if (empty($form) || !in_array($module->id, array_keys($modules))) {
|
||||
$modform = new \core_completion_defaultedit_form(null, [
|
||||
'course' => $course,
|
||||
'modules' => [
|
||||
$module->id => $module,
|
||||
],
|
||||
'displaycancel' => false,
|
||||
]);
|
||||
$module->modulecollapsed = true;
|
||||
}
|
||||
$module->formhtml = $modform->render();
|
||||
}
|
||||
}
|
||||
|
||||
return parent::render_from_template('core_course/defaultactivitycompletion', $data);
|
||||
}
|
||||
|
||||
@@ -103,8 +126,12 @@ class core_course_bulk_activity_completion_renderer extends plugin_renderer_base
|
||||
* @param moodleform $form
|
||||
* @param array $modules
|
||||
* @return string
|
||||
* @deprecated since Moodle 4.3 MDL-78528
|
||||
* @todo MDL-78711 This will be deleted in Moodle 4.7
|
||||
*/
|
||||
public function edit_default_completion($form, $modules) {
|
||||
debugging('edit_default_completion() is deprecated and will be removed.', DEBUG_DEVELOPER);
|
||||
|
||||
ob_start();
|
||||
$form->display();
|
||||
$formhtml = ob_get_contents();
|
||||
|
||||
@@ -28,6 +28,7 @@ require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->libdir.'/completionlib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT); // Course id.
|
||||
$modids = optional_param_array('modids', [], PARAM_INT);
|
||||
|
||||
// Perform some basic access control checks.
|
||||
if ($id) {
|
||||
@@ -56,9 +57,24 @@ $PAGE->set_title($course->shortname);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
$PAGE->set_pagelayout('admin');
|
||||
|
||||
// Get all that stuff I need for the renderer.
|
||||
$manager = new \core_completion\manager($id);
|
||||
$activityresourcedata = $manager->get_activities_and_resources();
|
||||
// Get list of modules that have been sent in the form.
|
||||
$manager = new \core_completion\manager($course->id);
|
||||
$allmodules = $manager->get_activities_and_resources(false);
|
||||
$modules = [];
|
||||
foreach ($allmodules->modules as $module) {
|
||||
if ($module->canmanage && in_array($module->id, $modids)) {
|
||||
$modules[$module->id] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
$form = null;
|
||||
if (!empty($modules)) {
|
||||
$form = new core_completion_defaultedit_form(null, ['course' => $course, 'modules' => $modules, 'displaycancel' => false]);
|
||||
if (!$form->is_cancelled() && $data = $form->get_data()) {
|
||||
$data->modules = $modules;
|
||||
$manager->apply_default_completion($data, $form->has_custom_completion_rules(), $form->get_suffix());
|
||||
}
|
||||
}
|
||||
|
||||
$renderer = $PAGE->get_renderer('core_course', 'bulk_activity_completion');
|
||||
|
||||
@@ -68,8 +84,6 @@ echo $OUTPUT->header();
|
||||
$actionbar = new \core_course\output\completion_action_bar($course->id, $PAGE->url);
|
||||
echo $renderer->render_course_completion_action_bar($actionbar);
|
||||
|
||||
$PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['theform']);
|
||||
|
||||
echo $renderer->defaultcompletion($activityresourcedata);
|
||||
echo $renderer->defaultcompletion($allmodules, $modules, $form);
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Bulk activity completion selection
|
||||
*
|
||||
* @package core_completion
|
||||
* @copyright 2017 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . "/../config.php");
|
||||
require_once($CFG->libdir . '/completionlib.php');
|
||||
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
$modids = optional_param_array('modids', [], PARAM_INT);
|
||||
$course = get_course($courseid);
|
||||
require_login($course);
|
||||
|
||||
navigation_node::override_active_url(new moodle_url('/course/completion.php', array('id' => $course->id)));
|
||||
$PAGE->set_url(new moodle_url('/course/editdefaultcompletion.php', ['id' => $courseid]));
|
||||
$PAGE->set_title($course->shortname);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
$PAGE->set_pagelayout('admin');
|
||||
|
||||
require_capability('moodle/course:manageactivities', context_course::instance($course->id));
|
||||
|
||||
// Prepare list of selected modules.
|
||||
$manager = new \core_completion\manager($course->id);
|
||||
$allmodules = $manager->get_activities_and_resources();
|
||||
$modules = [];
|
||||
foreach ($allmodules->modules as $module) {
|
||||
if ($module->canmanage && in_array($module->id, $modids)) {
|
||||
$modules[$module->id] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
$returnurl = new moodle_url('/course/defaultcompletion.php', ['id' => $course->id]);
|
||||
if (empty($modules)) {
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
$form = new core_completion_defaultedit_form(null, ['course' => $course, 'modules' => $modules]);
|
||||
|
||||
if ($form->is_cancelled()) {
|
||||
redirect($returnurl);
|
||||
} else if ($data = $form->get_data()) {
|
||||
$manager->apply_default_completion($data, $form->has_custom_completion_rules());
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
$renderer = $PAGE->get_renderer('core_course', 'bulk_activity_completion');
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading(get_string('defaultcompletion', 'completion'));
|
||||
|
||||
echo $renderer->edit_default_completion($form, $modules);
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
+3
-2
@@ -846,10 +846,11 @@ function get_moduleinfo_data($cm, $course) {
|
||||
* @param stdClass $course course object
|
||||
* @param string $modulename module name
|
||||
* @param int $section section number
|
||||
* @param string $suffix the suffix to add to the name of the completion rules.
|
||||
* @return array module information about other required data
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function prepare_new_moduleinfo_data($course, $modulename, $section) {
|
||||
function prepare_new_moduleinfo_data($course, $modulename, $section, string $suffix = '') {
|
||||
global $CFG;
|
||||
|
||||
list($module, $context, $cw) = can_add_moduleinfo($course, $modulename, $section);
|
||||
@@ -870,7 +871,7 @@ function prepare_new_moduleinfo_data($course, $modulename, $section) {
|
||||
$data->downloadcontent = DOWNLOAD_COURSE_CONTENT_ENABLED;
|
||||
|
||||
// Apply completion defaults.
|
||||
$defaults = \core_completion\manager::get_default_completion($course, $module);
|
||||
$defaults = \core_completion\manager::get_default_completion($course, $module, true, $suffix);
|
||||
foreach ($defaults as $key => $value) {
|
||||
$data->$key = $value;
|
||||
}
|
||||
|
||||
@@ -36,95 +36,48 @@
|
||||
}
|
||||
}}
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col">{{#str}}bulkactivitydetail, core_completion{{/str}}</div>
|
||||
<div class="row my-5 defaultactivitycompletion-header">
|
||||
<div class="col">{{#str}}defaultactivitycompletion, core_completion{{/str}}</div>
|
||||
</div>
|
||||
<form method="post" action="editdefaultcompletion.php" class="mform" id="theform">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<input type="submit" value="{{#str}}edit{{/str}}" class="btn btn-primary" name="submitbutton" aria-label="{{#str}}updateactivities, completion{{/str}}" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<div class="col-6">
|
||||
<input type="checkbox" class="mastercheck mr-1" aria-label="{{#str}}checkall, completion{{/str}}">
|
||||
<label class="font-weight-bold">{{#str}}activitieslabel, core_completion{{/str}}</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="font-weight-bold">{{#str}}completion, core_completion{{/str}}</label>
|
||||
<span>{{{helpicon}}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="row">
|
||||
<div class="modules">
|
||||
|
||||
<div class="modules pt-3">
|
||||
{{#modules}}
|
||||
{{#canmanage}}
|
||||
<div class="mb-1">
|
||||
<div class="row mb-1">
|
||||
<div class="col-6">
|
||||
<label class="accesshide" for="modtype_{{id}}">{{#str}}select, core_completion{{/str}} {{formattedname}}</label>
|
||||
<input id="modtype_{{id}}" type="checkbox" class="mr-1" name="modids[]" value="{{id}}" aria-label="{{#str}}checkactivity, completion, {{{formattedname}}}{{/str}}">
|
||||
<img class="iconlarge activityicon" src="{{icon}}" alt=" " role="presentation" />
|
||||
<span>{{{formattedname}}}</span>
|
||||
</div>
|
||||
<div class="activity-completionstatus col-6">
|
||||
<div class="col-sm-1 pl-0">
|
||||
{{#completionstatus.icon}}
|
||||
{{{completionstatus.icon}}}
|
||||
{{/completionstatus.icon}}
|
||||
{{^completionstatus.icon}}
|
||||
<span class="mr-3"></span>
|
||||
{{/completionstatus.icon}}
|
||||
</div>
|
||||
<div class="col-sm-11 pl-0">
|
||||
<span class="text-muted muted">{{{completionstatus.string}}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="defaultactivitycompletion-item d-flex"
|
||||
id="activitycompletion-{{id}}"
|
||||
>
|
||||
<a data-toggle="collapse"
|
||||
href="#activitycompletioncollapse-{{id}}"
|
||||
class="icons-collapse-expand {{#modulecollapsed}}collapsed{{/modulecollapsed}}"
|
||||
aria-expanded="{{^modulecollapsed}}true{{/modulecollapsed}}{{#modulecollapsed}}false{{/modulecollapsed}}"
|
||||
role="button"
|
||||
>
|
||||
<span class="collapsed-icon icon-no-margin mr-1"
|
||||
title="{{#str}} expandcategory, core, {{formattedname}} {{/str}}">
|
||||
<span class="dir-rtl-hide">{{#pix}} t/collapsedchevron, core {{/pix}}</span>
|
||||
<span class="dir-ltr-hide">{{#pix}} t/collapsedchevron_rtl, core {{/pix}}</span>
|
||||
<span class="sr-only">{{#str}} expandcategory, core, {{formattedname}} {{/str}}</span>
|
||||
</span>
|
||||
<span class="expanded-icon icon-no-margin mr-1"
|
||||
title="{{#str}} collapsecategory, core, {{formattedname}} {{/str}}">
|
||||
{{#pix}} t/expandedchevron, core {{/pix}}
|
||||
<span class="sr-only">{{#str}} collapsecategory, core, {{formatedname}} {{/str}}</span>
|
||||
</span>
|
||||
<img class="iconlarge activityicon ml-4" src="{{icon}}" alt="" aria-hidden="true">
|
||||
<h3 class="activityname ml-3 mb-0">{{{formattedname}}}</h3>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="row">
|
||||
<div id="activitycompletioncollapse-{{id}}"
|
||||
class="defaultactivitycompletion-item-content collapse multi-collapse {{^modulecollapsed}}show{{/modulecollapsed}}"
|
||||
aria-labelledby="activitycompletion-{{id}}" role="group"
|
||||
data-region="activitycompletion-{{name}}"
|
||||
>
|
||||
<hr class="row">
|
||||
<div class="py-3">{{{formhtml}}}</div>
|
||||
</div>
|
||||
|
||||
<hr class="row">
|
||||
{{/canmanage}}
|
||||
{{/modules}}
|
||||
</div>
|
||||
<input type="hidden" name="id" value="{{courseid}}" />
|
||||
<input type="hidden" name="sesskey" value="{{sesskey}}" />
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type="submit" value="{{#str}}edit{{/str}}" class="btn btn-primary" name="submitbutton" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{#js}}
|
||||
require([
|
||||
'jquery',
|
||||
], function($) {
|
||||
$('.mastercheck').click(function() {
|
||||
var checked = $('.mastercheck').is(':checked');
|
||||
$('input[type=checkbox]').each(function() {
|
||||
$(this).prop('checked', checked);
|
||||
$(this).trigger('change');
|
||||
});
|
||||
});
|
||||
|
||||
$('input[type=checkbox][id^=modtype_]').change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$('[name=submitbutton]').removeAttr('disabled');
|
||||
} else {
|
||||
// Is this the last activity checkbox to be un-checked? If so, disable the edit button.
|
||||
var somechecked = false;
|
||||
$('input[type=checkbox][id^=modtype_]').each(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
somechecked = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (!somechecked) {
|
||||
$('[name=submitbutton]').attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
|
||||
@@ -80,6 +80,50 @@ class modlib_test extends \advanced_testcase {
|
||||
prepare_new_moduleinfo_data($course, $assignmodule->name, $sectionnumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test prepare_new_moduleinfo_data with suffix (which is currently only used by the completion rules).
|
||||
* @covers ::prepare_new_moduleinfo_data
|
||||
*/
|
||||
public function test_prepare_new_moduleinfo_data_with_suffix() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
// Test with a complex module, like assign.
|
||||
$assignmodule = $DB->get_record('modules', ['name' => 'assign'], '*', MUST_EXIST);
|
||||
$sectionnumber = 1;
|
||||
|
||||
$suffix = 'mysuffix';
|
||||
[$module, $context, $cw, $cm, $data] = prepare_new_moduleinfo_data($course, $assignmodule->name, $sectionnumber, $suffix);
|
||||
$this->assertEquals($assignmodule, $module);
|
||||
$this->assertEquals($coursecontext, $context);
|
||||
$this->assertNull($cm); // Not cm yet.
|
||||
|
||||
$expecteddata = new \stdClass();
|
||||
$expecteddata->section = $sectionnumber;
|
||||
$expecteddata->visible = 1;
|
||||
$expecteddata->course = $course->id;
|
||||
$expecteddata->module = $module->id;
|
||||
$expecteddata->modulename = $module->name;
|
||||
$expecteddata->groupmode = $course->groupmode;
|
||||
$expecteddata->groupingid = $course->defaultgroupingid;
|
||||
$expecteddata->id = '';
|
||||
$expecteddata->instance = '';
|
||||
$expecteddata->coursemodule = '';
|
||||
$expecteddata->advancedgradingmethod_submissions = ''; // Not grading methods enabled by default.
|
||||
$expecteddata->{'completion' . $suffix} = 0;
|
||||
$expecteddata->downloadcontent = DOWNLOAD_COURSE_CONTENT_ENABLED;
|
||||
|
||||
// Unset untestable.
|
||||
unset($data->introeditor);
|
||||
unset($data->_advancedgradingdata);
|
||||
|
||||
$this->assertEquals($expecteddata, $data);
|
||||
$this->assertFalse(property_exists($data, 'completion'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_moduleinfo_data
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,8 @@ information provided here is intended especially for developers.
|
||||
* The `core_course_renderer::course_section_cm_completion` method has been removed, and can no longer be used
|
||||
* External function core_course_external::get_course_contents() now returns a new field activitybadge with the data to display
|
||||
the activity badge when the module implements it.
|
||||
* prepare_new_moduleinfo_data() now accepts a parameter "suffix" that will be added to the name of the completion rules.
|
||||
* The method core_course_bulk_activity_completion_renderer:: edit_default_completion() has been deprecated and will be removed.
|
||||
|
||||
=== 4.2 ===
|
||||
* course/mod.php now accepts parameter beforemod for adding course modules. It contains the course module id
|
||||
|
||||
@@ -144,6 +144,7 @@ $string['datepassed'] = 'Date passed';
|
||||
$string['days'] = 'Days';
|
||||
$string['daysoftotal'] = '{$a->days} of {$a->total}';
|
||||
$string['daysuntilcompletion'] = 'Days until completion';
|
||||
$string['defaultactivitycompletion'] = 'These are the default completion conditions for activities in all courses.';
|
||||
$string['defaultcompletion'] = 'Default activity completion';
|
||||
$string['defaultcompletionupdated'] = 'Changes saved';
|
||||
$string['deletecompletiondata'] = 'Delete completion data';
|
||||
|
||||
@@ -319,10 +319,13 @@ class mod_assign_mod_form extends moodleform_mod {
|
||||
public function add_completion_rules() {
|
||||
$mform =& $this->_form;
|
||||
|
||||
$mform->addElement('advcheckbox', 'completionsubmit', '', get_string('completionsubmit', 'assign'));
|
||||
$suffix = $this->get_suffix();
|
||||
$completionsubmitel = 'completionsubmit' . $suffix;
|
||||
$mform->addElement('advcheckbox', $completionsubmitel, '', get_string('completionsubmit', 'assign'));
|
||||
// Enable this completion rule by default.
|
||||
$mform->setDefault('completionsubmit', 1);
|
||||
return array('completionsubmit');
|
||||
$mform->setDefault($completionsubmitel, 1);
|
||||
|
||||
return [$completionsubmitel];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,7 +335,8 @@ class mod_assign_mod_form extends moodleform_mod {
|
||||
* @return bool
|
||||
*/
|
||||
public function completion_rule_enabled($data) {
|
||||
return !empty($data['completionsubmit']);
|
||||
$suffix = $this->get_suffix();
|
||||
return !empty($data['completionsubmit' . $suffix]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -143,10 +143,14 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
public function data_preprocessing(&$defaultvalues) {
|
||||
parent::data_preprocessing($defaultvalues);
|
||||
|
||||
$suffix = $this->get_suffix();
|
||||
$completionattendanceenabledel = 'completionattendanceenabled' . $suffix;
|
||||
$completionattendanceel = 'completionattendance' . $suffix;
|
||||
|
||||
// Completion: tick by default if completion attendance settings is set to 1 or more.
|
||||
$defaultvalues['completionattendanceenabled'] = 0;
|
||||
if (!empty($defaultvalues['completionattendance'])) {
|
||||
$defaultvalues['completionattendanceenabled'] = 1;
|
||||
$defaultvalues[$completionattendanceenabledel] = 0;
|
||||
if (!empty($defaultvalues[$completionattendanceel])) {
|
||||
$defaultvalues[$completionattendanceenabledel] = 1;
|
||||
}
|
||||
// Check if we are Editing an existing instance.
|
||||
if ($this->current->instance) {
|
||||
@@ -162,9 +166,9 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
return;
|
||||
}
|
||||
// Completion: tick if completion attendance settings is set to 1 or more.
|
||||
$defaultvalues['completionattendanceenabled'] = 0;
|
||||
if (!empty($this->current->completionattendance)) {
|
||||
$defaultvalues['completionattendanceenabled'] = 1;
|
||||
$defaultvalues[$completionattendanceenabledel] = 0;
|
||||
if (!empty($this->current->{$completionattendanceel})) {
|
||||
$defaultvalues[$completionattendanceenabledel] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,19 +208,26 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
return [];
|
||||
}
|
||||
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
// Elements for completion by Attendance.
|
||||
$attendance['grouplabel'] = get_string('completionattendancegroup', 'bigbluebuttonbn');
|
||||
$attendance['rulelabel'] = get_string('completionattendance', 'bigbluebuttonbn');
|
||||
$completionattendanceenabledel = 'completionattendanceenabled' . $suffix;
|
||||
$completionattendanceel = 'completionattendance' . $suffix;
|
||||
$completionattendanceunitel = 'completionattendanceunit' . $suffix;
|
||||
$attendance['group'] = [
|
||||
$mform->createElement('advcheckbox', 'completionattendanceenabled', '', $attendance['rulelabel'] . ' '),
|
||||
$mform->createElement('text', 'completionattendance', '', ['size' => 3]),
|
||||
$mform->createElement('static', 'completionattendanceunit', ' ', get_string('minutes', 'bigbluebuttonbn'))
|
||||
$mform->createElement('advcheckbox', $completionattendanceenabledel, '', $attendance['rulelabel'] . ' '),
|
||||
$mform->createElement('text', $completionattendanceel, '', ['size' => 3]),
|
||||
$mform->createElement('static', $completionattendanceunitel, ' ', get_string('minutes', 'bigbluebuttonbn'))
|
||||
];
|
||||
$mform->setType('completionattendance', PARAM_INT);
|
||||
$mform->addGroup($attendance['group'], 'completionattendancegroup', $attendance['grouplabel'], [' '], false);
|
||||
$mform->addHelpButton('completionattendancegroup', 'completionattendancegroup', 'bigbluebuttonbn');
|
||||
$mform->disabledIf('completionattendancegroup', 'completion', 'neq', COMPLETION_AGGREGATION_ANY);
|
||||
$mform->disabledIf('completionattendance', 'completionattendanceenabled', 'notchecked');
|
||||
$mform->setType($completionattendanceel, PARAM_INT);
|
||||
$completionattendancegroupel = 'completionattendancegroup' . $suffix;
|
||||
$mform->addGroup($attendance['group'], $completionattendancegroupel, $attendance['grouplabel'], ' ', false);
|
||||
$mform->addHelpButton($completionattendancegroupel, 'completionattendancegroup', 'bigbluebuttonbn');
|
||||
$completionel = 'completion' . $suffix;
|
||||
$mform->disabledIf($completionattendancegroupel, $completionel, 'neq', COMPLETION_AGGREGATION_ANY);
|
||||
$mform->disabledIf($completionattendanceel, $completionattendanceenabledel, 'notchecked');
|
||||
|
||||
// Elements for completion by Engagement.
|
||||
$engagement['grouplabel'] = get_string('completionengagementgroup', 'bigbluebuttonbn');
|
||||
@@ -225,23 +236,30 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
$engagement['raisehand'] = get_string('completionengagementraisehand', 'bigbluebuttonbn');
|
||||
$engagement['pollvotes'] = get_string('completionengagementpollvotes', 'bigbluebuttonbn');
|
||||
$engagement['emojis'] = get_string('completionengagementemojis', 'bigbluebuttonbn');
|
||||
|
||||
$completionengagementchatsel = 'completionengagementchats' . $suffix;
|
||||
$completionengagementtalksel = 'completionengagementtalks' . $suffix;
|
||||
$completionengagementraisehandel = 'completionengagementraisehand' . $suffix;
|
||||
$completionengagementpollvotesel = 'completionengagementpollvotes' . $suffix;
|
||||
$completionengagementemojisel = 'completionengagementemojis' . $suffix;
|
||||
$engagement['group'] = [
|
||||
$mform->createElement('advcheckbox', 'completionengagementchats', '', $engagement['chatlabel'] . ' '),
|
||||
$mform->createElement('advcheckbox', 'completionengagementtalks', '', $engagement['talklabel'] . ' '),
|
||||
$mform->createElement('advcheckbox', 'completionengagementraisehand', '', $engagement['raisehand'] . ' '),
|
||||
$mform->createElement('advcheckbox', 'completionengagementpollvotes', '', $engagement['pollvotes'] . ' '),
|
||||
$mform->createElement('advcheckbox', 'completionengagementemojis', '', $engagement['emojis'] . ' '),
|
||||
$mform->createElement('advcheckbox', $completionengagementchatsel, '', $engagement['chatlabel'] . ' '),
|
||||
$mform->createElement('advcheckbox', $completionengagementtalksel, '', $engagement['talklabel'] . ' '),
|
||||
$mform->createElement('advcheckbox', $completionengagementraisehandel, '', $engagement['raisehand'] . ' '),
|
||||
$mform->createElement('advcheckbox', $completionengagementpollvotesel, '', $engagement['pollvotes'] . ' '),
|
||||
$mform->createElement('advcheckbox', $completionengagementemojisel, '', $engagement['emojis'] . ' '),
|
||||
];
|
||||
$mform->addGroup($engagement['group'], 'completionengagementgroup', $engagement['grouplabel'], [' '], false);
|
||||
$mform->addGroupRule('completionattendancegroup', [
|
||||
'completionattendance' => [
|
||||
$completionengagementgroupel = 'completionengagementgroup' . $suffix;
|
||||
$mform->addGroup($engagement['group'], $completionengagementgroupel, $engagement['grouplabel'], ' ', false);
|
||||
$mform->addGroupRule($completionattendancegroupel, [
|
||||
$completionattendanceel => [
|
||||
[null, 'numeric', null, 'client']
|
||||
]
|
||||
]);
|
||||
$mform->addHelpButton('completionengagementgroup', 'completionengagementgroup', 'bigbluebuttonbn');
|
||||
$mform->disabledIf('completionengagementgroup', 'completion', 'neq', COMPLETION_AGGREGATION_ANY);
|
||||
$mform->addHelpButton($completionengagementgroupel, 'completionengagementgroup', 'bigbluebuttonbn');
|
||||
$mform->disabledIf($completionengagementgroupel, $completionel, 'neq', COMPLETION_AGGREGATION_ANY);
|
||||
|
||||
return ['completionattendancegroup', 'completionengagementgroup'];
|
||||
return [$completionattendancegroupel, $completionengagementgroupel];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,12 +269,13 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
* @return bool True if one or more rules is enabled, false if none are.
|
||||
*/
|
||||
public function completion_rule_enabled($data) {
|
||||
return (!empty($data['completionattendanceenabled']) && $data['completionattendance'] != 0)
|
||||
|| !empty($data['completionengagementchats'])
|
||||
|| !empty($data['completionengagementtalks'])
|
||||
|| !empty($data['completionengagementraisehand'])
|
||||
|| !empty($data['completionengagementpollvotes'])
|
||||
|| !empty($data['completionengagementemojis']);
|
||||
$suffix = $this->get_suffix();
|
||||
return (!empty($data['completionattendanceenabled' . $suffix]) && $data['completionattendance' . $suffix] != 0)
|
||||
|| !empty($data['completionengagementchats' . $suffix])
|
||||
|| !empty($data['completionengagementtalks' . $suffix])
|
||||
|| !empty($data['completionengagementraisehand' . $suffix])
|
||||
|| !empty($data['completionengagementpollvotes' . $suffix])
|
||||
|| !empty($data['completionengagementemojis' . $suffix]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,9 +290,11 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
parent::data_postprocessing($data);
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
if (!empty($data->completionunlocked)) {
|
||||
$autocompletion = !empty($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->completionattendanceenabled) || !$autocompletion) {
|
||||
$data->completionattendance = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->{'completionattendanceenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionattendance' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -703,7 +724,10 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod {
|
||||
$completion = new completion_info($COURSE);
|
||||
if ($completion->is_enabled()) {
|
||||
$mform = $this->_form;
|
||||
foreach (['completionattendancegroup', 'completionengagementgroup'] as $groupname) {
|
||||
$suffix = $this->get_suffix();
|
||||
$completionattendancegroupel = 'completionattendancegroup' . $suffix;
|
||||
$completionengagementgroupel = 'completionengagementgroup' . $suffix;
|
||||
foreach ([$completionattendancegroupel, $completionengagementgroupel] as $groupname) {
|
||||
if ($mform->elementExists($groupname)) {
|
||||
$element = $mform->getElement($groupname);
|
||||
if ($element->isFrozen()) {
|
||||
|
||||
+13
-10
@@ -138,10 +138,11 @@ class mod_choice_mod_form extends moodleform_mod {
|
||||
*/
|
||||
public function data_postprocessing($data) {
|
||||
parent::data_postprocessing($data);
|
||||
// Set up completion section even if checkbox is not ticked
|
||||
// Set up completion section even if checkbox is not ticked.
|
||||
if (!empty($data->completionunlocked)) {
|
||||
if (empty($data->completionsubmit)) {
|
||||
$data->completionsubmit = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
if (empty($data->{'completionsubmit' . $suffix})) {
|
||||
$data->{'completionsubmit' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,17 +166,19 @@ class mod_choice_mod_form extends moodleform_mod {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
function add_completion_rules() {
|
||||
public function add_completion_rules() {
|
||||
$mform =& $this->_form;
|
||||
|
||||
$mform->addElement('checkbox', 'completionsubmit', '', get_string('completionsubmit', 'choice'));
|
||||
$suffix = $this->get_suffix();
|
||||
$completionsubmitel = 'completionsubmit' . $suffix;
|
||||
$mform->addElement('checkbox', $completionsubmitel, '', get_string('completionsubmit', 'choice'));
|
||||
// Enable this completion rule by default.
|
||||
$mform->setDefault('completionsubmit', 1);
|
||||
return array('completionsubmit');
|
||||
$mform->setDefault($completionsubmitel, 1);
|
||||
return [$completionsubmitel];
|
||||
}
|
||||
|
||||
function completion_rule_enabled($data) {
|
||||
return !empty($data['completionsubmit']);
|
||||
public function completion_rule_enabled($data) {
|
||||
$suffix = $this->get_suffix();
|
||||
return !empty($data['completionsubmit' . $suffix]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+45
-18
@@ -123,19 +123,37 @@ class mod_data_mod_form extends moodleform_mod {
|
||||
*/
|
||||
public function add_completion_rules() {
|
||||
$mform = & $this->_form;
|
||||
$group = array();
|
||||
$group[] = $mform->createElement('checkbox', 'completionentriesenabled', '',
|
||||
get_string('completionentriescount', 'data'));
|
||||
$group[] = $mform->createElement('text', 'completionentries',
|
||||
get_string('completionentriescount', 'data'), array('size' => '1'));
|
||||
$group = [];
|
||||
|
||||
$mform->addGroup($group, 'completionentriesgroup', get_string('completionentries', 'data'),
|
||||
array(' '), false);
|
||||
$mform->disabledIf('completionentries', 'completionentriesenabled', 'notchecked');
|
||||
$mform->setDefault('completionentries', 1);
|
||||
$mform->setType('completionentries', PARAM_INT);
|
||||
$suffix = $this->get_suffix();
|
||||
$completionentriesenabledel = 'completionentriesenabled' . $suffix;
|
||||
$group[] = $mform->createElement(
|
||||
'checkbox',
|
||||
$completionentriesenabledel,
|
||||
'',
|
||||
get_string('completionentriescount', 'data')
|
||||
);
|
||||
$completionentriesel = 'completionentries' . $suffix;
|
||||
$group[] = $mform->createElement(
|
||||
'text',
|
||||
$completionentriesel,
|
||||
get_string('completionentriescount', 'data'),
|
||||
['size' => '1']
|
||||
);
|
||||
|
||||
$completionentriesgroupel = 'completionentriesgroup' . $suffix;
|
||||
$mform->addGroup(
|
||||
$group,
|
||||
$completionentriesgroupel,
|
||||
get_string('completionentries', 'data'),
|
||||
[' '],
|
||||
false
|
||||
);
|
||||
$mform->disabledIf($completionentriesel, $completionentriesenabledel, 'notchecked');
|
||||
$mform->setDefault($completionentriesel, 1);
|
||||
$mform->setType($completionentriesel, PARAM_INT);
|
||||
/* This ensures the elements are disabled unless completion rules are enabled */
|
||||
return array('completionentriesgroup');
|
||||
return [$completionentriesgroupel];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +163,8 @@ class mod_data_mod_form extends moodleform_mod {
|
||||
* @return bool True if one or more rules is enabled, false if none are.
|
||||
*/
|
||||
public function completion_rule_enabled($data) {
|
||||
return (!empty($data['completionentriesenabled']) && $data['completionentries'] != 0);
|
||||
$suffix = $this->get_suffix();
|
||||
return (!empty($data['completionentriesenabled' . $suffix]) && $data['completionentries' . $suffix] != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,9 +175,13 @@ class mod_data_mod_form extends moodleform_mod {
|
||||
*/
|
||||
public function data_preprocessing(&$defaultvalues) {
|
||||
parent::data_preprocessing($defaultvalues);
|
||||
$defaultvalues['completionentriesenabled'] = !empty($defaultvalues['completionentries']) ? 1 : 0;
|
||||
if (empty($defaultvalues['completionentries'])) {
|
||||
$defaultvalues['completionentries'] = 1;
|
||||
|
||||
$suffix = $this->get_suffix();
|
||||
$completionentriesenabledel = 'completionentriesenabled' . $suffix;
|
||||
$completionentriesel = 'completionentries' . $suffix;
|
||||
$defaultvalues[$completionentriesenabledel] = !empty($defaultvalues[$completionentriesel]) ? 1 : 0;
|
||||
if (empty($defaultvalues[$completionentriesel])) {
|
||||
$defaultvalues[$completionentriesel] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,9 +196,13 @@ class mod_data_mod_form extends moodleform_mod {
|
||||
public function data_postprocessing($data) {
|
||||
parent::data_postprocessing($data);
|
||||
if (!empty($data->completionunlocked)) {
|
||||
$autocompletion = !empty($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->completionentriesenabled) || !$autocompletion) {
|
||||
$data->completionentries = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completionel = 'completion' . $suffix;
|
||||
$completionentriesenabledel = 'completionentriesenabled' . $suffix;
|
||||
$autocompletion = !empty($data->{$completionel}) && $data->{$completionel} == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->{$completionentriesenabledel}) || !$autocompletion) {
|
||||
$completionentriesel = 'completionentries' . $suffix;
|
||||
$data->{$completionentriesel} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-11
@@ -175,11 +175,12 @@ class mod_feedback_mod_form extends moodleform_mod {
|
||||
$data->page_after_submit = $data->page_after_submit_editor['text'];
|
||||
|
||||
if (!empty($data->completionunlocked)) {
|
||||
// Turn off completion settings if the checkboxes aren't ticked
|
||||
$autocompletion = !empty($data->completion) &&
|
||||
$data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (!$autocompletion || empty($data->completionsubmit)) {
|
||||
$data->completionsubmit=0;
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (!$autocompletion || empty($data->{'completionsubmit' . $suffix})) {
|
||||
$data->{'completionsubmit' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,16 +207,20 @@ class mod_feedback_mod_form extends moodleform_mod {
|
||||
public function add_completion_rules() {
|
||||
$mform =& $this->_form;
|
||||
|
||||
$suffix = $this->get_suffix();
|
||||
$completionsubmitel = 'completionsubmit' . $suffix;
|
||||
$mform->addElement('checkbox',
|
||||
'completionsubmit',
|
||||
'',
|
||||
get_string('completionsubmit', 'feedback'));
|
||||
$completionsubmitel,
|
||||
'',
|
||||
get_string('completionsubmit', 'feedback')
|
||||
);
|
||||
// Enable this completion rule by default.
|
||||
$mform->setDefault('completionsubmit', 1);
|
||||
return array('completionsubmit');
|
||||
$mform->setDefault($completionsubmitel, 1);
|
||||
return [$completionsubmitel];
|
||||
}
|
||||
|
||||
public function completion_rule_enabled($data) {
|
||||
return !empty($data['completionsubmit']);
|
||||
$suffix = $this->get_suffix();
|
||||
return !empty($data['completionsubmit' . $suffix]);
|
||||
}
|
||||
}
|
||||
|
||||
+73
-47
@@ -405,30 +405,36 @@ class mod_forum_mod_form extends moodleform_mod {
|
||||
}
|
||||
}
|
||||
|
||||
function data_preprocessing(&$default_values) {
|
||||
parent::data_preprocessing($default_values);
|
||||
public function data_preprocessing(&$defaultvalues) {
|
||||
parent::data_preprocessing($defaultvalues);
|
||||
|
||||
$suffix = $this->get_suffix();
|
||||
$completiondiscussionsenabledel = 'completiondiscussionsenabled' . $suffix;
|
||||
$completiondiscussionsel = 'completiondiscussions' . $suffix;
|
||||
$completionrepliesenabledel = 'completionrepliesenabled' . $suffix;
|
||||
$completionrepliesel = 'completionreplies' . $suffix;
|
||||
$completionpostsel = 'completionposts' . $suffix;
|
||||
$completionpostsenabledel = 'completionpostsenabled' . $suffix;
|
||||
|
||||
// Set up the completion checkboxes which aren't part of standard data.
|
||||
// We also make the default value (if you turn on the checkbox) for those
|
||||
// numbers to be 1, this will not apply unless checkbox is ticked.
|
||||
$default_values['completiondiscussionsenabled']=
|
||||
!empty($default_values['completiondiscussions']) ? 1 : 0;
|
||||
if (empty($default_values['completiondiscussions'])) {
|
||||
$default_values['completiondiscussions']=1;
|
||||
$defaultvalues[$completiondiscussionsenabledel] = !empty($defaultvalues[$completiondiscussionsel]) ? 1 : 0;
|
||||
if (empty($defaultvalues[$completiondiscussionsel])) {
|
||||
$defaultvalues[$completiondiscussionsel] = 1;
|
||||
}
|
||||
$default_values['completionrepliesenabled']=
|
||||
!empty($default_values['completionreplies']) ? 1 : 0;
|
||||
if (empty($default_values['completionreplies'])) {
|
||||
$default_values['completionreplies']=1;
|
||||
$defaultvalues[$completionrepliesenabledel] = !empty($defaultvalues[$completionrepliesel]) ? 1 : 0;
|
||||
if (empty($defaultvalues[$completionrepliesel])) {
|
||||
$defaultvalues[$completionrepliesel] = 1;
|
||||
}
|
||||
// Tick by default if Add mode or if completion posts settings is set to 1 or more.
|
||||
if (empty($this->_instance) || !empty($default_values['completionposts'])) {
|
||||
$default_values['completionpostsenabled'] = 1;
|
||||
if (empty($this->_instance) || !empty($defaultvalues[$completionpostsel])) {
|
||||
$defaultvalues[$completionpostsenabledel] = 1;
|
||||
} else {
|
||||
$default_values['completionpostsenabled'] = 0;
|
||||
$defaultvalues[$completionpostsenabledel] = 0;
|
||||
}
|
||||
if (empty($default_values['completionposts'])) {
|
||||
$default_values['completionposts']=1;
|
||||
if (empty($defaultvalues[$completionpostsel])) {
|
||||
$defaultvalues[$completionpostsel] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,36 +444,54 @@ class mod_forum_mod_form extends moodleform_mod {
|
||||
* @return array Array of string IDs of added items, empty array if none
|
||||
*/
|
||||
public function add_completion_rules() {
|
||||
$mform =& $this->_form;
|
||||
$mform = $this->_form;
|
||||
|
||||
$group=array();
|
||||
$group[] =& $mform->createElement('checkbox', 'completionpostsenabled', '', get_string('completionposts','forum'));
|
||||
$group[] =& $mform->createElement('text', 'completionposts', '', array('size'=>3));
|
||||
$mform->setType('completionposts',PARAM_INT);
|
||||
$mform->addGroup($group, 'completionpostsgroup', get_string('completionpostsgroup','forum'), array(' '), false);
|
||||
$mform->disabledIf('completionposts','completionpostsenabled','notchecked');
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
$group=array();
|
||||
$group[] =& $mform->createElement('checkbox', 'completiondiscussionsenabled', '', get_string('completiondiscussions','forum'));
|
||||
$group[] =& $mform->createElement('text', 'completiondiscussions', '', array('size'=>3));
|
||||
$mform->setType('completiondiscussions',PARAM_INT);
|
||||
$mform->addGroup($group, 'completiondiscussionsgroup', get_string('completiondiscussionsgroup','forum'), array(' '), false);
|
||||
$mform->disabledIf('completiondiscussions','completiondiscussionsenabled','notchecked');
|
||||
$group = [];
|
||||
$completionpostsenabledel = 'completionpostsenabled' . $suffix;
|
||||
$group[] =& $mform->createElement('checkbox', $completionpostsenabledel, '', get_string('completionposts', 'forum'));
|
||||
$completionpostsel = 'completionposts' . $suffix;
|
||||
$group[] =& $mform->createElement('text', $completionpostsel, '', ['size' => 3]);
|
||||
$mform->setType($completionpostsel, PARAM_INT);
|
||||
$completionpostsgroupel = 'completionpostsgroup' . $suffix;
|
||||
$mform->addGroup($group, $completionpostsgroupel, get_string('completionpostsgroup', 'forum'), ' ', false);
|
||||
$mform->disabledIf($completionpostsel, $completionpostsenabledel, 'notchecked');
|
||||
|
||||
$group=array();
|
||||
$group[] =& $mform->createElement('checkbox', 'completionrepliesenabled', '', get_string('completionreplies','forum'));
|
||||
$group[] =& $mform->createElement('text', 'completionreplies', '', array('size'=>3));
|
||||
$mform->setType('completionreplies',PARAM_INT);
|
||||
$mform->addGroup($group, 'completionrepliesgroup', get_string('completionrepliesgroup','forum'), array(' '), false);
|
||||
$mform->disabledIf('completionreplies','completionrepliesenabled','notchecked');
|
||||
$group = [];
|
||||
$completiondiscussionsenabledel = 'completiondiscussionsenabled' . $suffix;
|
||||
$group[] =& $mform->createElement(
|
||||
'checkbox',
|
||||
$completiondiscussionsenabledel,
|
||||
'',
|
||||
get_string('completiondiscussions',
|
||||
'forum')
|
||||
);
|
||||
$completiondiscussionsel = 'completiondiscussions' . $suffix;
|
||||
$group[] =& $mform->createElement('text', $completiondiscussionsel, '', ['size' => 3]);
|
||||
$mform->setType($completiondiscussionsel, PARAM_INT);
|
||||
$completiondiscussionsgroupel = 'completiondiscussionsgroup' . $suffix;
|
||||
$mform->addGroup($group, $completiondiscussionsgroupel, get_string('completiondiscussionsgroup', 'forum'), ' ', false);
|
||||
$mform->disabledIf($completiondiscussionsel, $completiondiscussionsenabledel, 'notchecked');
|
||||
|
||||
return array('completiondiscussionsgroup','completionrepliesgroup','completionpostsgroup');
|
||||
$group = [];
|
||||
$completionrepliesenabledel = 'completionrepliesenabled' . $suffix;
|
||||
$group[] =& $mform->createElement('checkbox', $completionrepliesenabledel, '', get_string('completionreplies', 'forum'));
|
||||
$completionrepliesel = 'completionreplies' . $suffix;
|
||||
$group[] =& $mform->createElement('text', $completionrepliesel, '', ['size' => 3]);
|
||||
$mform->setType($completionrepliesel, PARAM_INT);
|
||||
$completionrepliesgroupel = 'completionrepliesgroup' . $suffix;
|
||||
$mform->addGroup($group, $completionrepliesgroupel, get_string('completionrepliesgroup', 'forum'), ' ', false);
|
||||
$mform->disabledIf($completionrepliesel, $completionrepliesenabledel, 'notchecked');
|
||||
|
||||
return [$completiondiscussionsgroupel, $completionrepliesgroupel, $completionpostsgroupel];
|
||||
}
|
||||
|
||||
function completion_rule_enabled($data) {
|
||||
return (!empty($data['completiondiscussionsenabled']) && $data['completiondiscussions']!=0) ||
|
||||
(!empty($data['completionrepliesenabled']) && $data['completionreplies']!=0) ||
|
||||
(!empty($data['completionpostsenabled']) && $data['completionposts']!=0);
|
||||
public function completion_rule_enabled($data) {
|
||||
$suffix = $this->get_suffix();
|
||||
return (!empty($data['completiondiscussionsenabled' . $suffix]) && $data['completiondiscussions' . $suffix] != 0) ||
|
||||
(!empty($data['completionrepliesenabled' . $suffix]) && $data['completionreplies' . $suffix] != 0) ||
|
||||
(!empty($data['completionpostsenabled' . $suffix]) && $data['completionposts' . $suffix] != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,17 +530,19 @@ class mod_forum_mod_form extends moodleform_mod {
|
||||
*/
|
||||
public function data_postprocessing($data) {
|
||||
parent::data_postprocessing($data);
|
||||
// Turn off completion settings if the checkboxes aren't ticked
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
if (!empty($data->completionunlocked)) {
|
||||
$autocompletion = !empty($data->completion) && $data->completion==COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->completiondiscussionsenabled) || !$autocompletion) {
|
||||
$data->completiondiscussions = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->{'completiondiscussionsenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completiondiscussions' . $suffix} = 0;
|
||||
}
|
||||
if (empty($data->completionrepliesenabled) || !$autocompletion) {
|
||||
$data->completionreplies = 0;
|
||||
if (empty($data->{'completionrepliesenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionreplies' . $suffix} = 0;
|
||||
}
|
||||
if (empty($data->completionpostsenabled) || !$autocompletion) {
|
||||
$data->completionposts = 0;
|
||||
if (empty($data->{'completionpostsenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionposts' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-25
@@ -163,43 +163,57 @@ class mod_glossary_mod_form extends moodleform_mod {
|
||||
}
|
||||
}
|
||||
|
||||
function data_preprocessing(&$default_values){
|
||||
parent::data_preprocessing($default_values);
|
||||
public function data_preprocessing(&$defaultvalues) {
|
||||
parent::data_preprocessing($defaultvalues);
|
||||
|
||||
// Fallsback on the default setting if 'Entries shown per page' has been left blank.
|
||||
// This prevents the field from being required and expand its section which should not
|
||||
// be the case if there is a default value defined.
|
||||
if (empty($default_values['entbypage']) || $default_values['entbypage'] < 0) {
|
||||
$default_values['entbypage'] = $this->get_default_entbypage();
|
||||
if (empty($defaultvalues['entbypage']) || $defaultvalues['entbypage'] < 0) {
|
||||
$defaultvalues['entbypage'] = $this->get_default_entbypage();
|
||||
}
|
||||
|
||||
$suffix = $this->get_suffix();
|
||||
$completionentriesel = 'completionentries' . $suffix;
|
||||
$completionentriesenabledel = 'completionentriesenabled' . $suffix;
|
||||
|
||||
// Set up the completion checkboxes which aren't part of standard data.
|
||||
// Tick by default if Add mode or if completion entries settings is set to 1 or more.
|
||||
if (empty($this->_instance) || !empty($default_values['completionentries'])) {
|
||||
$default_values['completionentriesenabled'] = 1;
|
||||
if (empty($this->_instance) || !empty($defaultvalues[$completionentriesel])) {
|
||||
$defaultvalues[$completionentriesenabledel] = 1;
|
||||
} else {
|
||||
$default_values['completionentriesenabled'] = 0;
|
||||
$defaultvalues[$completionentriesenabledel] = 0;
|
||||
}
|
||||
if (empty($default_values['completionentries'])) {
|
||||
$default_values['completionentries']=1;
|
||||
if (empty($defaultvalues[$completionentriesel])) {
|
||||
$defaultvalues[$completionentriesel] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function add_completion_rules() {
|
||||
$mform =& $this->_form;
|
||||
public function add_completion_rules() {
|
||||
$mform = $this->_form;
|
||||
$suffix = $this->get_suffix();
|
||||
|
||||
$group=array();
|
||||
$group[] =& $mform->createElement('checkbox', 'completionentriesenabled', '', get_string('completionentries','glossary'));
|
||||
$group[] =& $mform->createElement('text', 'completionentries', '', array('size'=>3));
|
||||
$mform->setType('completionentries', PARAM_INT);
|
||||
$mform->addGroup($group, 'completionentriesgroup', get_string('completionentriesgroup','glossary'), array(' '), false);
|
||||
$mform->disabledIf('completionentries','completionentriesenabled','notchecked');
|
||||
$group = [];
|
||||
$completionentriesenabledel = 'completionentriesenabled' . $suffix;
|
||||
$group[] =& $mform->createElement(
|
||||
'checkbox',
|
||||
$completionentriesenabledel,
|
||||
'',
|
||||
get_string('completionentries', 'glossary')
|
||||
);
|
||||
$completionentriesel = 'completionentries' . $suffix;
|
||||
$group[] =& $mform->createElement('text', $completionentriesel, '', ['size' => 3]);
|
||||
$mform->setType($completionentriesel, PARAM_INT);
|
||||
$completionentriesgroupel = 'completionentriesgroup' . $suffix;
|
||||
$mform->addGroup($group, $completionentriesgroupel, get_string('completionentriesgroup', 'glossary'), ' ', false);
|
||||
$mform->disabledIf($completionentriesel, $completionentriesenabledel, 'notchecked');
|
||||
|
||||
return array('completionentriesgroup');
|
||||
return [$completionentriesgroupel];
|
||||
}
|
||||
|
||||
function completion_rule_enabled($data) {
|
||||
return (!empty($data['completionentriesenabled']) && $data['completionentries']!=0);
|
||||
public function completion_rule_enabled($data) {
|
||||
$suffix = $this->get_suffix();
|
||||
return (!empty($data['completionentriesenabled' . $suffix]) && $data['completionentries' . $suffix] != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,10 +227,12 @@ class mod_glossary_mod_form extends moodleform_mod {
|
||||
public function data_postprocessing($data) {
|
||||
parent::data_postprocessing($data);
|
||||
if (!empty($data->completionunlocked)) {
|
||||
// Turn off completion settings if the checkboxes aren't ticked
|
||||
$autocompletion = !empty($data->completion) && $data->completion==COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->completionentriesenabled) || !$autocompletion) {
|
||||
$data->completionentries = 0;
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->{'completionentriesenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionentries' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,4 +248,3 @@ class mod_glossary_mod_form extends moodleform_mod {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+36
-20
@@ -365,8 +365,10 @@ class mod_lesson_mod_form extends moodleform_mod {
|
||||
}
|
||||
|
||||
// Set up the completion checkbox which is not part of standard data.
|
||||
$defaultvalues['completiontimespentenabled'] =
|
||||
!empty($defaultvalues['completiontimespent']) ? 1 : 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completiontimespentenabledel = 'completiontimespentenabled' . $suffix;
|
||||
$completiontimespentel = 'completiontimespent' . $suffix;
|
||||
$defaultvalues[$completiontimespentenabledel] = !empty($defaultvalues[$completiontimespentel]) ? 1 : 0;
|
||||
|
||||
if ($this->current->instance) {
|
||||
// Editing existing instance - copy existing files into draft area.
|
||||
@@ -406,20 +408,32 @@ class mod_lesson_mod_form extends moodleform_mod {
|
||||
public function add_completion_rules() {
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('checkbox', 'completionendreached', get_string('completionendreached', 'lesson'),
|
||||
get_string('completionendreached_desc', 'lesson'));
|
||||
$suffix = $this->get_suffix();
|
||||
$completionendreachedel = 'completionendreached' . $suffix;
|
||||
$mform->addElement(
|
||||
'checkbox', $completionendreachedel,
|
||||
get_string('completionendreached', 'lesson'),
|
||||
get_string('completionendreached_desc', 'lesson')
|
||||
);
|
||||
// Enable this completion rule by default.
|
||||
$mform->setDefault('completionendreached', 1);
|
||||
$mform->setDefault($completionendreachedel, 1);
|
||||
|
||||
$group = array();
|
||||
$group[] =& $mform->createElement('checkbox', 'completiontimespentenabled', '',
|
||||
get_string('completiontimespent', 'lesson'));
|
||||
$group[] =& $mform->createElement('duration', 'completiontimespent', '', array('optional' => false));
|
||||
$mform->addGroup($group, 'completiontimespentgroup', get_string('completiontimespentgroup', 'lesson'), array(' '), false);
|
||||
$mform->disabledIf('completiontimespent[number]', 'completiontimespentenabled', 'notchecked');
|
||||
$mform->disabledIf('completiontimespent[timeunit]', 'completiontimespentenabled', 'notchecked');
|
||||
$group = [];
|
||||
$completiontimespentenabledel = 'completiontimespentenabled' . $suffix;
|
||||
$group[] =& $mform->createElement(
|
||||
'checkbox',
|
||||
$completiontimespentenabledel,
|
||||
'',
|
||||
get_string('completiontimespent', 'lesson')
|
||||
);
|
||||
$completiontimespentel = 'completiontimespent' . $suffix;
|
||||
$group[] =& $mform->createElement('duration', $completiontimespentel, '', ['optional' => false]);
|
||||
$completiontimespentgroupel = 'completiontimespentgroup' . $suffix;
|
||||
$mform->addGroup($group, $completiontimespentgroupel, get_string('completiontimespentgroup', 'lesson'), ' ', false);
|
||||
$mform->disabledIf($completiontimespentel . '[number]', $completiontimespentenabledel, 'notchecked');
|
||||
$mform->disabledIf($completiontimespentel . '[timeunit]', $completiontimespentenabledel, 'notchecked');
|
||||
|
||||
return array('completionendreached', 'completiontimespentgroup');
|
||||
return [$completionendreachedel, $completiontimespentgroupel];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,7 +443,8 @@ class mod_lesson_mod_form extends moodleform_mod {
|
||||
* @return bool True if one or more rules is enabled, false if none are.
|
||||
*/
|
||||
public function completion_rule_enabled($data) {
|
||||
return !empty($data['completionendreached']) || $data['completiontimespent'] > 0;
|
||||
$suffix = $this->get_suffix();
|
||||
return !empty($data['completionendreached' . $suffix]) || $data['completiontimespent' . $suffix] > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,14 +459,15 @@ class mod_lesson_mod_form extends moodleform_mod {
|
||||
parent::data_postprocessing($data);
|
||||
// Turn off completion setting if the checkbox is not ticked.
|
||||
if (!empty($data->completionunlocked)) {
|
||||
$autocompletion = !empty($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->completiontimespentenabled) || !$autocompletion) {
|
||||
$data->completiontimespent = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->{'completiontimespentenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completiontimespent' . $suffix} = 0;
|
||||
}
|
||||
if (empty($data->completionendreached) || !$autocompletion) {
|
||||
$data->completionendreached = 0;
|
||||
if (empty($data->{'completionendreached' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionendreached' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+45
-23
@@ -491,10 +491,13 @@ class mod_quiz_mod_form extends moodleform_mod {
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($toform['completionminattempts'])) {
|
||||
$toform['completionminattempts'] = 1;
|
||||
$suffix = $this->get_suffix();
|
||||
$completionminattemptsel = 'completionminattempts' . $suffix;
|
||||
if (empty($toform[$completionminattemptsel])) {
|
||||
$toform[$completionminattemptsel] = 1;
|
||||
} else {
|
||||
$toform['completionminattemptsenabled'] = $toform['completionminattempts'] > 0;
|
||||
$completionminattemptsenabledel = 'completionminattemptsenabled' . $suffix;
|
||||
$toform[$completionminattemptsenabledel] = $toform[$completionminattemptsel] > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,9 +513,11 @@ class mod_quiz_mod_form extends moodleform_mod {
|
||||
parent::data_postprocessing($data);
|
||||
if (!empty($data->completionunlocked)) {
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
$autocompletion = !empty($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->completionminattemptsenabled) || !$autocompletion) {
|
||||
$data->completionminattempts = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (empty($data->{'completionminattemptsenabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionminattempts' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -534,9 +539,12 @@ class mod_quiz_mod_form extends moodleform_mod {
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data['completionminattempts'])) {
|
||||
if ($data['attempts'] > 0 && $data['completionminattempts'] > $data['attempts']) {
|
||||
$errors['completionminattemptsgroup'] = get_string('completionminattemptserror', 'quiz');
|
||||
$suffix = $this->get_suffix();
|
||||
$completionminattemptsel = 'completionminattempts' . $suffix;
|
||||
if (!empty($data[$completionminattemptsel])) {
|
||||
if ($data['attempts'] > 0 && $data[$completionminattemptsel] > $data['attempts']) {
|
||||
$completionminattemptsgroupel = 'completionminattemptsgroup' . $suffix;
|
||||
$errors[$completionminattemptsgroupel] = get_string('completionminattemptserror', 'quiz');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,23 +615,36 @@ class mod_quiz_mod_form extends moodleform_mod {
|
||||
*/
|
||||
public function add_completion_rules() {
|
||||
$mform = $this->_form;
|
||||
$suffix = $this->get_suffix();
|
||||
$items = [];
|
||||
|
||||
$mform->addElement('advcheckbox', 'completionattemptsexhausted', null,
|
||||
$completionattemptsexhaustedel = 'completionattemptsexhausted' . $suffix;
|
||||
$mform->addElement(
|
||||
'advcheckbox',
|
||||
$completionattemptsexhaustedel,
|
||||
null,
|
||||
get_string('completionattemptsexhausted', 'quiz'),
|
||||
['group' => 'cattempts']);
|
||||
$mform->disabledIf('completionattemptsexhausted', 'completionpassgrade', 'notchecked');
|
||||
$items[] = 'completionattemptsexhausted';
|
||||
['group' => 'cattempts']
|
||||
);
|
||||
$completionpassgradeel = 'completionpassgrade' . $suffix;
|
||||
$mform->disabledIf($completionattemptsexhaustedel, $completionpassgradeel, 'notchecked');
|
||||
$items[] = $completionattemptsexhaustedel;
|
||||
|
||||
$group = [];
|
||||
$group[] = $mform->createElement('checkbox', 'completionminattemptsenabled', '',
|
||||
get_string('completionminattempts', 'quiz'));
|
||||
$group[] = $mform->createElement('text', 'completionminattempts', '', ['size' => 3]);
|
||||
$mform->setType('completionminattempts', PARAM_INT);
|
||||
$mform->addGroup($group, 'completionminattemptsgroup', get_string('completionminattemptsgroup', 'quiz'), [' '], false);
|
||||
$mform->disabledIf('completionminattempts', 'completionminattemptsenabled', 'notchecked');
|
||||
|
||||
$items[] = 'completionminattemptsgroup';
|
||||
$completionminattemptsenabledel = 'completionminattemptsenabled' . $suffix;
|
||||
$group[] = $mform->createElement(
|
||||
'checkbox',
|
||||
$completionminattemptsenabledel,
|
||||
'',
|
||||
get_string('completionminattempts', 'quiz')
|
||||
);
|
||||
$completionminattemptsel = 'completionminattempts' . $suffix;
|
||||
$group[] = $mform->createElement('text', $completionminattemptsel, '', ['size' => 3]);
|
||||
$mform->setType($completionminattemptsel, PARAM_INT);
|
||||
$completionminattemptsgroupel = 'completionminattemptsgroup' . $suffix;
|
||||
$mform->addGroup($group, $completionminattemptsgroupel, get_string('completionminattemptsgroup', 'quiz'), ' ', false);
|
||||
$mform->disabledIf($completionminattemptsel, $completionminattemptsenabledel, 'notchecked');
|
||||
$items[] = $completionminattemptsgroupel;
|
||||
|
||||
return $items;
|
||||
}
|
||||
@@ -635,8 +656,9 @@ class mod_quiz_mod_form extends moodleform_mod {
|
||||
* @return bool True if one or more rules is enabled, false if none are.
|
||||
*/
|
||||
public function completion_rule_enabled($data) {
|
||||
return !empty($data['completionattemptsexhausted']) ||
|
||||
!empty($data['completionminattemptsenabled']);
|
||||
$suffix = $this->get_suffix();
|
||||
return !empty($data['completionattemptsexhausted' . $suffix]) ||
|
||||
!empty($data['completionminattemptsenabled' . $suffix]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+58
-41
@@ -271,8 +271,10 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
$this->standard_coursemodule_elements();
|
||||
|
||||
// A SCORM module should define this within itself and is not needed here.
|
||||
if ($mform->elementExists('completionpassgrade')) {
|
||||
$mform->removeElement('completionpassgrade');
|
||||
$suffix = $this->get_suffix();
|
||||
$completionpassgradeel = 'completionpassgrade' . $suffix;
|
||||
if ($mform->elementExists($completionpassgradeel)) {
|
||||
$mform->removeElement($completionpassgradeel);
|
||||
}
|
||||
|
||||
// Buttons.
|
||||
@@ -332,24 +334,29 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
}
|
||||
|
||||
// Set some completion default data.
|
||||
$suffix = $this->get_suffix();
|
||||
$completionstatusrequiredel = 'completionstatusrequired' . $suffix;
|
||||
$cvalues = array();
|
||||
if (empty($this->_instance)) {
|
||||
// When in add mode, set a default completion rule that requires the SCORM's status be set to "Completed".
|
||||
$cvalues[4] = 1;
|
||||
} else if (!empty($defaultvalues['completionstatusrequired']) && !is_array($defaultvalues['completionstatusrequired'])) {
|
||||
if (!empty($defaultvalues[$completionstatusrequiredel]) && !is_array($defaultvalues[$completionstatusrequiredel])) {
|
||||
// Unpack values.
|
||||
foreach (scorm_status_options() as $key => $value) {
|
||||
if (($defaultvalues['completionstatusrequired'] & $key) == $key) {
|
||||
if (($defaultvalues[$completionstatusrequiredel] & $key) == $key) {
|
||||
$cvalues[$key] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($cvalues)) {
|
||||
$defaultvalues['completionstatusrequired'] = $cvalues;
|
||||
} else if (empty($this->_instance)) {
|
||||
// When in add mode, set a default completion rule that requires the SCORM's status be set to "Completed".
|
||||
$cvalues[4] = 1;
|
||||
}
|
||||
|
||||
if (!isset($defaultvalues['completionscorerequired']) || !strlen($defaultvalues['completionscorerequired'])) {
|
||||
$defaultvalues['completionscoredisabled'] = 1;
|
||||
if (!empty($cvalues)) {
|
||||
$defaultvalues[$completionstatusrequiredel] = $cvalues;
|
||||
}
|
||||
|
||||
$completionscorerequiredel = 'completionscorerequired' . $suffix;
|
||||
if (!isset($defaultvalues[$completionscorerequiredel]) || !strlen($defaultvalues[$completionscorerequiredel])) {
|
||||
$completionscoredisabledel = 'completionscoredisabled' . $suffix;
|
||||
$defaultvalues[$completionscoredisabledel] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,15 +454,18 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
$errors['timeclose'] = get_string('closebeforeopen', 'scorm');
|
||||
}
|
||||
}
|
||||
if (!empty($data['completionstatusallscos'])) {
|
||||
$suffix = $this->get_suffix();
|
||||
$completionstatusallscosel = 'completionstatusallscos' . $suffix;
|
||||
if (!empty($data[$completionstatusallscosel])) {
|
||||
$completionstatusrequiredel = 'completionstatusrequired' . $suffix;
|
||||
$requirestatus = false;
|
||||
foreach (scorm_status_options(true) as $key => $value) {
|
||||
if (!empty($data['completionstatusrequired'][$key])) {
|
||||
if (!empty($data[$completionstatusrequiredel][$key])) {
|
||||
$requirestatus = true;
|
||||
}
|
||||
}
|
||||
if (!$requirestatus) {
|
||||
$errors['completionstatusallscos'] = get_string('youmustselectastatus', 'scorm');
|
||||
$errors[$completionstatusallscosel] = get_string('youmustselectastatus', 'scorm');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,27 +500,31 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
}
|
||||
|
||||
public function add_completion_rules() {
|
||||
$suffix = $this->get_suffix();
|
||||
$mform =& $this->_form;
|
||||
$items = array();
|
||||
|
||||
// Require score.
|
||||
$group = array();
|
||||
$group[] =& $mform->createElement('text', 'completionscorerequired', '', array('size' => 5));
|
||||
$group = [];
|
||||
$completionscorerequiredel = 'completionscorerequired' . $suffix;
|
||||
$group[] =& $mform->createElement('text', $completionscorerequiredel, '', ['size' => 5]);
|
||||
$group[] =& $mform->createElement('checkbox', 'completionscoredisabled', null, get_string('disable'));
|
||||
$mform->setType('completionscorerequired', PARAM_INT);
|
||||
$mform->addGroup($group, 'completionscoregroup', get_string('completionscorerequired', 'scorm'), '', false);
|
||||
$mform->addHelpButton('completionscoregroup', 'completionscorerequired', 'scorm');
|
||||
$mform->disabledIf('completionscorerequired', 'completionscoredisabled', 'checked');
|
||||
$mform->setDefault('completionscorerequired', 0);
|
||||
$mform->setType($completionscorerequiredel, PARAM_INT);
|
||||
$completionscoregroupel = 'completionscoregroup' . $suffix;
|
||||
$mform->addGroup($group, $completionscoregroupel, get_string('completionscorerequired', 'scorm'), '', false);
|
||||
$mform->addHelpButton($completionscoregroupel, 'completionscorerequired', 'scorm');
|
||||
$mform->disabledIf($completionscorerequiredel, 'completionscoredisabled', 'checked');
|
||||
$mform->setDefault($completionscorerequiredel, 0);
|
||||
|
||||
$items[] = 'completionscoregroup';
|
||||
$items[] = $completionscoregroupel;
|
||||
|
||||
// Require status.
|
||||
$first = true;
|
||||
$firstkey = null;
|
||||
$completionstatusrequiredel = 'completionstatusrequired' . $suffix;
|
||||
foreach (scorm_status_options(true) as $key => $value) {
|
||||
$name = null;
|
||||
$key = 'completionstatusrequired['.$key.']';
|
||||
$key = $completionstatusrequiredel . '['.$key.']';
|
||||
if ($first) {
|
||||
$name = get_string('completionstatusrequired', 'scorm');
|
||||
$first = false;
|
||||
@@ -522,18 +536,20 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
}
|
||||
$mform->addHelpButton($firstkey, 'completionstatusrequired', 'scorm');
|
||||
|
||||
$mform->addElement('checkbox', 'completionstatusallscos', get_string('completionstatusallscos', 'scorm'));
|
||||
$mform->setType('completionstatusallscos', PARAM_BOOL);
|
||||
$mform->addHelpButton('completionstatusallscos', 'completionstatusallscos', 'scorm');
|
||||
$mform->setDefault('completionstatusallscos', 0);
|
||||
$items[] = 'completionstatusallscos';
|
||||
$completionstatusallscosel = 'completionstatusallscos' . $suffix;
|
||||
$mform->addElement('checkbox', $completionstatusallscosel, get_string('completionstatusallscos', 'scorm'));
|
||||
$mform->setType($completionstatusallscosel, PARAM_BOOL);
|
||||
$mform->addHelpButton($completionstatusallscosel, 'completionstatusallscos', 'scorm');
|
||||
$mform->setDefault($completionstatusallscosel, 0);
|
||||
$items[] = $completionstatusallscosel;
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function completion_rule_enabled($data) {
|
||||
$status = !empty($data['completionstatusrequired']);
|
||||
$score = empty($data['completionscoredisabled']) && strlen($data['completionscorerequired']);
|
||||
$suffix = $this->get_suffix();
|
||||
$status = !empty($data['completionstatusrequired' . $suffix]);
|
||||
$score = empty($data['completionscoredisabled' . $suffix]) && strlen($data['completionscorerequired' . $suffix]);
|
||||
|
||||
return $status || $score;
|
||||
}
|
||||
@@ -550,8 +566,9 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
parent::data_postprocessing($data);
|
||||
// Convert completionstatusrequired to a proper integer, if any.
|
||||
$total = 0;
|
||||
if (isset($data->completionstatusrequired) && is_array($data->completionstatusrequired)) {
|
||||
foreach ($data->completionstatusrequired as $state => $value) {
|
||||
$suffix = $this->get_suffix();
|
||||
if (isset($data->{'completionstatusrequired' . $suffix}) && is_array($data->{'completionstatusrequired' . $suffix})) {
|
||||
foreach ($data->{'completionstatusrequired' . $suffix} as $state => $value) {
|
||||
if ($value) {
|
||||
$total |= $state;
|
||||
}
|
||||
@@ -559,21 +576,21 @@ class mod_scorm_mod_form extends moodleform_mod {
|
||||
if (!$total) {
|
||||
$total = null;
|
||||
}
|
||||
$data->completionstatusrequired = $total;
|
||||
$data->{'completionstatusrequired' . $suffix} = $total;
|
||||
}
|
||||
|
||||
if (!empty($data->completionunlocked)) {
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
$autocompletion = isset($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = isset($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
|
||||
if (!(isset($data->completionstatusrequired) && $autocompletion)) {
|
||||
$data->completionstatusrequired = null;
|
||||
if (!(isset($data->{'completionstatusrequired' . $suffix}) && $autocompletion)) {
|
||||
$data->{'completionstatusrequired' . $suffix} = null;
|
||||
}
|
||||
// Else do nothing: completionstatusrequired has been already converted
|
||||
// into a correct integer representation.
|
||||
// Else do nothing: completionstatusrequired has been already converted into a correct integer representation.
|
||||
|
||||
if (!empty($data->completionscoredisabled) || !$autocompletion) {
|
||||
$data->completionscorerequired = null;
|
||||
if (!empty($data->{'completionscoredisabled' . $suffix}) || !$autocompletion) {
|
||||
$data->{'completionscorerequired' . $suffix} = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-11
@@ -58,10 +58,11 @@ class mod_survey_mod_form extends moodleform_mod {
|
||||
parent::data_postprocessing($data);
|
||||
if (!empty($data->completionunlocked)) {
|
||||
// Turn off completion settings if the checkboxes aren't ticked.
|
||||
$autocompletion = !empty($data->completion) &&
|
||||
$data->completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (!$autocompletion || empty($data->completionsubmit)) {
|
||||
$data->completionsubmit = 0;
|
||||
$suffix = $this->get_suffix();
|
||||
$completion = $data->{'completion' . $suffix};
|
||||
$autocompletion = !empty($completion) && $completion == COMPLETION_TRACKING_AUTOMATIC;
|
||||
if (!$autocompletion || empty($data->{'completionsubmit' . $suffix})) {
|
||||
$data->{'completionsubmit' . $suffix} = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,19 +73,21 @@ class mod_survey_mod_form extends moodleform_mod {
|
||||
*/
|
||||
public function add_completion_rules() {
|
||||
$mform =& $this->_form;
|
||||
$mform->addElement('checkbox', 'completionsubmit', '', get_string('completionsubmit', 'survey'));
|
||||
$suffix = $this->get_suffix();
|
||||
$completionsubmitel = 'completionsubmit' . $suffix;
|
||||
$mform->addElement('checkbox', $completionsubmitel, '', get_string('completionsubmit', 'survey'));
|
||||
// Enable this completion rule by default.
|
||||
$mform->setDefault('completionsubmit', 1);
|
||||
return array('completionsubmit');
|
||||
$mform->setDefault($completionsubmitel, 1);
|
||||
return [$completionsubmitel];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable completion rules
|
||||
* @param stdclass $data
|
||||
* @return array
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function completion_rule_enabled($data) {
|
||||
return !empty($data['completionsubmit']);
|
||||
$suffix = $this->get_suffix();
|
||||
return !empty($data['completionsubmit' . $suffix]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1784,3 +1784,19 @@ $activity-add-hover: theme-color-level('primary', -10) !default;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Activity completion */
|
||||
|
||||
.defaultactivitycompletion-item {
|
||||
a {
|
||||
color: $black;
|
||||
text-decoration: none;
|
||||
img {
|
||||
filter: invert(25%) sepia(86%) saturate(1158%) hue-rotate(189deg) brightness(104%) contrast(92%);
|
||||
}
|
||||
}
|
||||
.activityicon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29557,6 +29557,19 @@ span.editinstructions .alert-link {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
||||
/* Activity completion */
|
||||
.defaultactivitycompletion-item a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
.defaultactivitycompletion-item a img {
|
||||
filter: invert(25%) sepia(86%) saturate(1158%) hue-rotate(189deg) brightness(104%) contrast(92%);
|
||||
}
|
||||
.defaultactivitycompletion-item .activityicon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
/* Anchor link offset fix. This makes hash links scroll 60px down to account for the fixed header. */
|
||||
:target {
|
||||
scroll-margin-top: 70px;
|
||||
|
||||
@@ -29557,6 +29557,19 @@ span.editinstructions .alert-link {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
||||
/* Activity completion */
|
||||
.defaultactivitycompletion-item a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
.defaultactivitycompletion-item a img {
|
||||
filter: invert(25%) sepia(86%) saturate(1158%) hue-rotate(189deg) brightness(104%) contrast(92%);
|
||||
}
|
||||
.defaultactivitycompletion-item .activityicon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
/* Anchor link offset fix. This makes hash links scroll 60px down to account for the fixed header. */
|
||||
:target {
|
||||
scroll-margin-top: 60px;
|
||||
|
||||
Reference in New Issue
Block a user