Merge branch 'MDL-51447-500' of https://github.com/AnupamaSarjoshi/moodle into MOODLE_500_STABLE

This commit is contained in:
Huong Nguyen
2026-01-21 10:10:50 +07:00
4 changed files with 331 additions and 11 deletions
@@ -104,6 +104,9 @@ class block_completionstatus extends block_base {
// Flag to set if current completion data is inconsistent with what is stored in the database.
$pending_update = false;
// Get activities visible to the user that have completion enabled.
$visibleactivities = $info->get_user_activities_with_completion($USER->id);
// Loop through course criteria.
foreach ($completions as $completion) {
$criteria = $completion->get_criteria();
@@ -115,6 +118,11 @@ class block_completionstatus extends block_base {
// Activities are a special case, so cache them and leave them till last.
if ($criteria->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
// Only include activities that are visible to the user.
if (!isset($visibleactivities[$criteria->moduleinstance])) {
continue;
}
$activities[$criteria->moduleinstance] = $complete;
if ($complete) {
+11
View File
@@ -119,10 +119,21 @@ $pendingupdate = false;
// Load criteria to display.
$completions = $info->get_completions($user->id);
// Get activities visible to the user that have completion enabled.
$visibleactivities = $info->get_user_activities_with_completion($user->id);
// Loop through course criteria.
foreach ($completions as $completion) {
$criteria = $completion->get_criteria();
// Skip display of activity completion criteria for activities the user cannot see.
if (
$criteria->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY &&
!isset($visibleactivities[$criteria->moduleinstance])
) {
continue;
}
if (!$pendingupdate && $criteria->is_pending($completion)) {
$pendingupdate = true;
}
@@ -6,9 +6,10 @@ Feature: Enable Block Completion in a course using activity completion
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
And the following "courses" exist:
| fullname | shortname | category | enablecompletion |
| Course 1 | C1 | 0 | 1 |
@@ -16,6 +17,7 @@ Feature: Enable Block Completion in a course using activity completion
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And the following "activities" exist:
| activity | course | idnumber | name | gradepass | completion | completionview | completionusegrade | completionpassgrade |
| page | C1 | page1 | Test page name | | 2 | 1 | 0 | 0 |
@@ -23,10 +25,12 @@ Feature: Enable Block Completion in a course using activity completion
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| completionstatus | Course | C1 | course-view-* | side-pre |
And I am on the "Course 1" course page logged in as teacher1
And I change window size to "large"
And I turn editing mode on
Scenario: Completion status block when student has not started any activities
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Course completion" in current page administration
Given I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test page name | 1 |
@@ -36,8 +40,7 @@ Feature: Enable Block Completion in a course using activity completion
And I should see "0 of 1" in the "Activity completion" "table_row"
Scenario: Completion status block when student has completed a page
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Course completion" in current page administration
Given I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test page name | 1 |
@@ -50,8 +53,7 @@ Feature: Enable Block Completion in a course using activity completion
And I should see "Yes" in the "Activity completion" "table_row"
Scenario: Completion status block with items with passing grade
Given I am on the "Course 1" course page logged in as teacher1
And I navigate to "Course completion" in current page administration
Given I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Test assign name | 1 |
@@ -69,8 +71,7 @@ Feature: Enable Block Completion in a course using activity completion
And I should see "Yes" in the "Activity completion" "table_row"
Scenario: Completion status block with items with failing grade
Given I am on the "Course 1" course page logged in as teacher1
And the following "grade grades" exist:
Given the following "grade grades" exist:
| gradeitem | user | grade |
| Test assign name | student1 | 49 |
And I navigate to "Course completion" in current page administration
@@ -86,3 +87,265 @@ Feature: Enable Block Completion in a course using activity completion
And I follow "More details"
And I should see "Achieving grade, Achieving passing grade" in the "Activity completion" "table_row"
And I should see "No" in the "Activity completion" "table_row"
@javascript
Scenario: Student visibility respects combined activity and section restrictions with progressive completion
Given the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible | completion | completionview |
| page | task A | page description | C1 | page1 | 0 | 1 | 2 | 1 |
| page | task B | page description | C1 | page2 | 1 | 1 | 2 | 1 |
| assign | task C | assignment description | C1 | assign1 | 1 | 1 | 2 | 1 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
And I set the following fields to these values:
| Page - task A | 1 |
| Page - task B | 1 |
| Assignment - task C | 1 |
And I press "Save changes"
# Add conditionally visible restriction (open eye) to section 1 requiring task A completion.
And I turn editing mode on
And I edit the section "1"
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I set the field "Activity or resource" to "task A"
And I press "Save changes"
# Add conditionally hidden restriction (closed eye) to task C requiring task A completion.
And I am on the "task C" "assign activity editing" page
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I click on "Displayed if student doesn't meet this condition Click to hide" "link"
And I set the field "Activity or resource" to "task A"
And I press "Save and return to course"
And I log out
# Initial state: Only unrestricted visible activities appear.
When I am on the "Course 1" course page logged in as student1
Then I should see "Status: Not yet started"
And I should see "0 of 1" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "task A" in the "criteriastatus" "table"
And I should not see "task B" in the "criteriastatus" "table"
And I should not see "task C" in the "criteriastatus" "table"
# After completing task A: Section 2 activities become visible.
And I click on "task A" "link"
And I am on the "Course 1" course page logged in as student1
And I should see "Status: In progress"
And I should see "1 of 3" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "task A" in the "criteriastatus" "table"
And I should see "task B" in the "criteriastatus" "table"
And I should see "task C" in the "criteriastatus" "table"
@javascript
Scenario: Student completion view shows only accessible activities considering all activity restrictions
Given the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible | completion | completionview |
| page | task A | page description | C1 | page1 | 0 | 1 | 2 | 1 |
| page | task B | page description | C1 | assign1 | 1 | 1 | 2 | 1 |
| assign | task C | assignment description | C1 | assign2 | 1 | 1 | 2 | 1 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
# Set completion of the activities.
And I set the following fields to these values:
| Page - task A | 1 |
| Page - task B | 1 |
| Assignment - task C | 1 |
And I press "Save changes"
# Add conditionally visible restriction (open eye) to "task B".
And I am on the "task B" "page activity editing" page
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I set the field "Activity or resource" to "task A"
And I press "Save and return to course"
# Add conditionally hidden restriction (closed eye) to "task C".
And I am on the "task C" "assign activity editing" page
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I click on "Displayed if student doesn't meet this condition Click to hide" "link"
And I set the field "Activity or resource" to "task A"
And I press "Save and return to course"
When I am on the "Course 1" course page logged in as student1
And I should see "Status: Not yet started"
And I should see "0 of 2" in the "Activity completion" "table_row"
And I follow "More details"
Then I should see "task A" in the "criteriastatus" "table"
And I should see "task B" in the "criteriastatus" "table"
And I should not see "task C" in the "criteriastatus" "table"
And I click on "task A" "link"
# Complete task A to make task C visible.
And I am on the "Course 1" course page logged in as student1
And I should see "Status: In progress"
And I should see "1 of 3" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "task A" in the "criteriastatus" "table"
And I should see "task B" in the "criteriastatus" "table"
And I should see "task C" in the "criteriastatus" "table"
@javascript
Scenario: Hidden activities do not appear in the completion status block
Given the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible | completion | completionview |
| page | task A | page description | C1 | page1 | 0 | 1 | 2 | 1 |
| page | task B | page description | C1 | page2 | 0 | 0 | 2 | 1 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
# Set completion of the activities.
And I set the following fields to these values:
| Page - task A | 1 |
| Page - task B | 1 |
And I press "Save changes"
When I am on the "Course 1" course page logged in as student1
And I should see "Status: Not yet started"
And I should see "0 of 1" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "task A" in the "criteriastatus" "table"
Then I should not see "task B" in the "criteriastatus" "table"
@javascript
Scenario: Activities in the hidden section do not appear in the completion status block
Given the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible | completion | completionview |
| page | task A | page description | C1 | page1 | 0 | 1 | 2 | 1 |
| page | task B | page description | C1 | page2 | 1 | 1 | 2 | 1 |
| assign | task C | page description | C1 | page3 | 2 | 1 | 2 | 1 |
| assign | task D | page description | C1 | page4 | 3 | 1 | 2 | 1 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
# Set completion of the activities.
And I set the following fields to these values:
| Page - task A | 1 |
| Page - task B | 1 |
| Assignment - task C | 1 |
| Assignment - task D | 1 |
And I press "Save changes"
# Hide section 1 to make sure book activities are not visible to the student.
And I hide section "1"
# Add conditionally visible restriction to section 2.
And I edit the section "2"
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I set the field "Activity or resource" to "task A"
And I press "Save changes"
# Add conditionally hidden restriction to section 3.
And I am on the "Course 1" course page
And I edit the section "3"
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I set the field "Activity or resource" to "task A"
And I click on "Displayed if student doesn't meet this condition Click to hide" "link"
And I press "Save changes"
And I log out
When I am on the "Course 1" course page logged in as student1
And I should see "Status: Not yet started"
And I should see "0 of 1" in the "Activity completion" "table_row"
And I follow "More details"
Then I should see "task A" in the "criteriastatus" "table"
And I should not see "task B" in the "criteriastatus" "table"
And I should not see "task C" in the "criteriastatus" "table"
And I should not see "task D" in the "criteriastatus" "table"
# Complete task A to make other activities visible.
And I click on "task A" "link"
And I am on the "Course 1" course page logged in as student1
And I should see "Status: In progress"
And I should see "1 of 3" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "task A" in the "criteriastatus" "table"
And I should not see "task B" in the "criteriastatus" "table"
And I should see "task C" in the "criteriastatus" "table"
And I should see "task D" in the "criteriastatus" "table"
@javascript
Scenario: Activities with disabled completion tracking are omitted from the completion view
Given the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible | completion | completionview |
| page | task A | page description | C1 | page1 | 0 | 1 | 2 | 1 |
| page | task B | page description | C1 | page2 | 1 | 1 | 2 | 1 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
# Set completion of the activities.
And I set the following fields to these values:
| Page - task A | 1 |
| Page - task B | 1 |
And I press "Save changes"
# Disable completion tracking for "task A".
And I am on the "task A" "page activity editing" page
And I expand all fieldsets
And I set the following fields to these values:
| completion | 0 |
And I press "Save and return to course"
When I am on the "Course 1" course page logged in as student1
And I should see "Status: Not yet started"
And I should see "0 of 1" in the "Activity completion" "table_row"
And I follow "More details"
Then I should not see "task A" in the "criteriastatus" "table"
And I should see "task B" in the "criteriastatus" "table"
@javascript
Scenario: Activities with group or grouping restrictions are omitted from the completion view
Given the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible | completion | completionview |
| page | task A | page description | C1 | page1 | 0 | 1 | 2 | 1 |
| page | task B | page description | C1 | page2 | 1 | 1 | 2 | 1 |
| page | task C | page description | C1 | page3 | 2 | 1 | 2 | 1 |
And I navigate to "Course completion" in current page administration
And I expand all fieldsets
# Set completion of the activities.
And I set the following fields to these values:
| Page - task A | 1 |
| Page - task B | 1 |
| Page - task C | 1 |
And I press "Save changes"
# Add groups and groupings.
And the following "groups" exist:
| name | course | idnumber |
| G1 | C1 | GI1 |
| G2 | C1 | GI2 |
And the following "groupings" exist:
| name | course | idnumber |
| Grouping 1 | C1 | GG1 |
| Grouping 2 | C1 | GG2 |
And the following "grouping groups" exist:
| grouping | group |
| GG1 | GI1 |
| GG2 | GI2 |
# Add students to groups.
And the following "group members" exist:
| user | group |
| student1 | GI1 |
| student2 | GI2 |
# Add group restriction to "task B".
And I am on the "task B" "page activity editing" page
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Group" "button" in the "Add restriction..." "dialogue"
And I set the field "Group" to "G1"
And I click on "Save and return to course" "button"
# Add Grouping and 'Activity or resource' restriction to "task C".
And I am on the "task C" "page activity editing" page
And I expand all fieldsets
And I click on "Add restriction..." "button"
And I click on "Grouping" "button" in the "Add restriction..." "dialogue"
And I set the field "Grouping" to "Grouping 2"
And I click on "Add restriction..." "button"
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
And I set the field "Activity or resource" to "task A"
And I click on "Save and return to course" "button"
When I am on the "Course 1" course page logged in as student1
And I should see "Status: Not yet started"
And I should see "0 of 2" in the "Activity completion" "table_row"
And I follow "More details"
Then I should see "task A" in the "criteriastatus" "table"
And I should see "task B" in the "criteriastatus" "table"
And I should not see "task C" in the "criteriastatus" "table"
And I am on the "Course 1" course page logged in as student2
And I should see "Status: Not yet started"
And I should see "0 of 2" in the "Activity completion" "table_row"
And I follow "More details"
And I should see "task A" in the "criteriastatus" "table"
And I should not see "task B" in the "criteriastatus" "table"
And I should see "task C" in the "criteriastatus" "table"
+38
View File
@@ -1345,6 +1345,44 @@ class completion_info {
return $result;
}
/**
* Return a list of activities that are visible on the course page and have completion enabled.
*
* This includes activities that the user can see on the course page (visible or restricted),
* but only those with completion tracking enabled. Activities hidden from
* the user, located in hidden sections or restricted by group/grouping are excluded.
*
* @param int $userid User id
* @return array Array of user visible activities with completion enabled.
*/
public function get_user_activities_with_completion($userid): array {
$visible = [];
$activities = $this->get_activities();
foreach ($activities as $cm) {
// Step 1: Exclude activities hidden from the user on the course page.
if (!$cm->is_visible_on_course_page()) {
continue;
}
// Step 2: Check if the user is excluded by group or grouping style restrictions.
$info = new \core_availability\info_module($cm);
$users = [$userid => (object)['id' => $userid]];
$users = $info->filter_user_list($users);
if (empty($users)) {
// The user was removed from the list, meaning user list restrictions apply.
// This is where group and grouping restrictions exclude the user.
continue;
}
// If we reach here, count this activity for completion details and percentage.
$visible[$cm->id] = 1;
}
return $visible;
}
/**
* Checks to see if the userid supplied has a tracked role in
* this course