Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
mickhawkins authored Aug 14, 2023
2 parents 17c7573 + 442263c commit 4b99507
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 18 deletions.
2 changes: 2 additions & 0 deletions data/moodle-contributors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ Ligne
Lillekjendlie
Limekiller
Lior
Lipson
Lloyd
Lock
Logan
Expand Down Expand Up @@ -701,6 +702,7 @@ Miletic
Milette
Miller
Milling
Miri
Mirko
Misha
Mitin
Expand Down
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

:::

0 comments on commit 4b99507

Please sign in to comment.