Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDL-78528 - [docs] Append a suffix to the completion rules #699

Merged
merged 1 commit into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 63 additions & 18 deletions docs/apis/core/activitycompletion/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ title: Activity completion API
tags:
- Conditional activities
- API
documentationDraft: true
---

import { Since } from '@site/src/components';

:::note
There are changes to the completion API introduced in **Moodle 3.11** to be incorporated to this page. Please refer to [Student activity completion](https://docs.moodle.org/dev/Student_activity_completion) for details.
:::
Expand Down Expand Up @@ -86,7 +87,7 @@ Implementing custom completion rules is more complex than using the system-provi

To implement custom completion rules, you need to:

1. Return true for FEATURE_COMPLETION_HAS_RULES in your activity's _supports function.
1. Return true for `FEATURE_COMPLETION_HAS_RULES` in your activity's `_supports` function.
1. Add database fields to your activity's main table to store the custom completion settings.
1. Add backup and restore code to back up these fields.
1. Add information about the completion settings to the activities cm_info object.
Expand Down Expand Up @@ -197,6 +198,19 @@ When you have custom completion conditions, you need to add controls to your mod
- Implement the `completion_rule_enabled` function which is called during form validation to check whether one of your activity's completion rules has been selected.
- Implement other form changes if necessary to set up the form with your data. If your data is in the form of simple text boxes or dropdowns then this is not necessary, but you might want to have a checkbox that enables the rule with a separate control to set its value. This needs form tweaks.

<Since
version="4.3"
issueNumber="MDL-78528"
/>

The default completion form has undergone a significant rebuild to enhance code reusability and maintainability. To prevent duplicate IDs, a suffix has been introduced to the form elements related to completion rules.

:::info From Moodle 4.3 onwards

Any custom completion rules added will need to use `$this->get_suffix()`.

:::

#### Example

The forum offers a checkbox with a text input box beside it. You tick the checkbox to enable the rule, then type in the desired number of posts.
Expand All @@ -215,15 +229,43 @@ public function add_completion_rules() {
$mform = $this->_form;

$group = [
$mform->createElement('checkbox', 'completionpostsenabled', ' ', get_string('completionposts', 'forum')),
$mform->createElement('text', 'completionposts', ' ', ['size' => 3]),
$mform->createElement(
'checkbox',
$this->get_suffixed_name('completionpostsenabled'),
' ',
get_string('completionposts', 'forum')
),
$mform->createElement(
'text',
$this->get_suffixed_name('completionposts'),
' ',
['size' => 3]
),
];
$mform->setType('completionposts', PARAM_INT);
$mform->addGroup($group, 'completionpostsgroup', get_string('completionpostsgroup','forum'), [' '], false);
$mform->addHelpButton('completionpostsgroup', 'completionposts', 'forum');
$mform->disabledIf('completionposts', 'completionpostsenabled', 'notchecked');
$mform->addGroup(
$group,
$this->get_suffixed_name('completionpostsgroup'),
get_string('completionpostsgroup','forum'),
[' '],
false
);
$mform->addHelpButton(
$this->get_suffixed_name('completionpostsgroup'),
'completionposts',
'forum'
);
$mform->disabledIf(
$this->get_suffixed_name('completionposts'),
$this->get_suffixed_name('completionpostsenabled'),
'notchecked'
);

return [$this->get_suffixed_name('completionpostsgroup')];
}

return ['completionpostsgroup'];
protected function get_suffixed_name(string $fieldname): string {
return $fieldname . $this->get_suffix();
}
```

Expand All @@ -232,6 +274,7 @@ public function add_completion_rules() {
- The text input field is disabled if the checkbox isn't ticked.
- Note that this function must return the top-level element associated with the completion rule. (If there are multiple elements, you can return more than one.)
- This is used so that your controls become disabled if automatic completion is not selected.

Next, a function for checking whether the user selected this option:

```php
Expand All @@ -242,13 +285,14 @@ Next, a function for checking whether the user selected this option:
* @return bool True if one or more rules is enabled, false if none are.
*/
public function completion_rule_enabled($data) {
return (!empty($data['completionpostsenabled']) && $data['completionposts'] != 0);
return (!empty($data[$this->get_suffixed_name('completionpostsenabled')]) &&
$data[$this->get_suffixed_name('completionposts')] != 0);
}
```

- The custom completion rule is enabled if the 'enabled' checkbox is ticked and the text field value is something other than zero.
- This is used to give an error if the user selects automatic completion, but fails to select any conditions.
That's all the 'required' functions, but we need to add some extra code to support the checkbox behaviour. I overrode get_data so that if there is a value in the edit field, but the checkbox is not ticked, the value counts as zero (the rule will not be enabled).
That's all the 'required' functions, but we need to add some extra code to support the checkbox behaviour. I overrode `get_data` so that if there is a value in the edit field, but the checkbox is not ticked, the value counts as zero (the rule will not be enabled).

```php
function get_data() {
Expand All @@ -257,10 +301,11 @@ function get_data() {
return $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->completionpostsenabled) || !$autocompletion) {
$data->completionposts = 0;
// Turn off completion settings if the checkboxes aren't ticked.
$autocompletion = !empty($data->{$this->get_suffixed_name('completion')}) &&
$data->{$this->get_suffixed_name('completion')} == COMPLETION_TRACKING_AUTOMATIC;
if (empty($data->{$this->get_suffixed_name('completionpostsenabled')}) || !$autocompletion) {
$data->{$this->get_suffixed_name('completionposts')} = 0;
}
}
return $data;
Expand All @@ -277,10 +322,10 @@ function data_preprocessing(&$default_values){
// 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['completionpostsenabled']=
!empty($default_values['completionposts']) ? 1 : 0;
if(empty($default_values['completionposts'])) {
$default_values['completionposts']=1;
$default_values[$this->get_suffixed_name('completionpostsenabled')] =
!empty($default_values[$this->get_suffixed_name('completionposts')]) ? 1 : 0;
if (empty($default_values[$this->get_suffixed_name('completionposts')])) {
$default_values[$this->get_suffixed_name('completionposts')] = 1;
}
}
```
Expand Down
46 changes: 46 additions & 0 deletions docs/devupdate.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,49 @@ if (!empty($showonly)) {
$mform->filter_shown_headers(explode(',', $showonly));
}
```

## Activity completion

### Append a suffix to the completion rules

As part of [MDL-78516](https://tracker.moodle.org/browse/MDL-78516), the [Default completion form](https://docs.moodle.org/en/Activity_completion_settings#Changing_activity_completion_settings_in_bulk) has undergone a significant rebuild to enhance code reusability and maintainability. To prevent duplicate IDs, a suffix has been introduced to the form elements related to completion rules.

For third-party plugins, an adjustment is needed to incorporate this new suffix, following the approach already taken by [core modules](https://github.com/sarjona/moodle/commit/8f57f0fdaca027c7099bc6966467077aecbc0862).

The primary modification entails editing `mod/yourplugin/mod_form.php` and applying the suffix to the completion rule elements within all relevant methods. As an example, here are the changes made to the `mod/choice` module:

```php
public function add_completion_rules() {
$mform = $this->_form;

$completionsubmitel = $this->get_suffixed_name('completionsubmit');
$mform->addElement('checkbox', $completionsubmitel, '', get_string('completionsubmit', 'choice'));
// Enable this completion rule by default.
$mform->setDefault($completionsubmitel, 1);
return [$completionsubmitel];
}

public function completion_rule_enabled($data) {
return !empty($data[$this->get_suffixed_name('completionsubmit')]);
}

public function data_postprocessing($data) {
parent::data_postprocessing($data);
// Set up completion section even if checkbox is not ticked.
if (!empty($data->completionunlocked)) {
if (empty($data->{$this->get_suffixed_name('completionsubmit')})) {
$data->{$this->get_suffixed_name('completionsubmit')} = 0;
}
}
}

protected function get_suffixed_name(string $fieldname): string {
return $fieldname . $this->get_suffix();
}
```

:::caution

Starting from Moodle 4.3, completion rules without the suffix will be phased out from the [Default completion form](https://docs.moodle.org/en/Activity_completion_settings#Changing_activity_completion_settings_in_bulk) until they are updated to incorporate the required suffix

:::
Loading