Skip to content

Error when self-unenrolling from a course causes fill_from_queue() to fail #36

@mi-dave

Description

@mi-dave

When a student self-unenrols from a course, they are deregistered from the groups, but no-one is moved from the waiting list because fill_from_queue() fails.

Steps to reproduce:

  • Create a course with self-enrolment enabled
  • Add a Grouptool instance to it
  • Set "If group members get removed" to "Follow changes"
  • Create a group with only 1 place available and queues enabled
  • As Student 1, enrol in the course and register for the session
  • As Student 2, enrol in the course and join the queue for the session
  • As Student 1, unenrol from the course

If debugdisplay is enabled, it now outputs:

Exception encountered in event observer '\mod_grouptool\observer::group_member_removed': Sorry, but you do not currently have permissions to do that (View active groups).

  • line 2695 of /mod/grouptool/locallib.php: call to require_capability()
  • line 2835 of /mod/grouptool/locallib.php: call to mod_grouptool->get_active_groups()
  • line 182 of /mod/grouptool/classes/observer.php: call to mod_grouptool->fill_from_queue()
  • line ? of unknownfile: call to mod_grouptool\observer::group_member_removed()
  • line 155 of /lib/classes/event/manager.php: call to call_user_func()
  • line 75 of /lib/classes/event/manager.php: call to core\event\manager::process_buffers()
  • line 795 of /lib/classes/event/base.php: call to core\event\manager::dispatch()
  • line 233 of /group/lib.php: call to core\event\base->trigger()
  • line 689 of /group/lib.php: call to groups_remove_member()
  • line 2295 of /lib/enrollib.php: call to groups_delete_group_members()
  • line 51 of /enrol/self/unenrolself.php: call to enrol_plugin->unenrol_user()

This is because mod_grouptool\observer::group_member_removed() calls $instance->fill_from_queue() which calls $this->get_active_groups() which calls require_capability('mod/grouptool:view_groups') - but Student 1 no longer has that permission because they are no longer a student on that course.

As a result, now no-one is registered for that group, but the queue still has one person in it.

I don't think get_active_groups() should be checking permissions at all when called from fill_from_queue(), as the latter should work no matter what capabilities the currently logged in user has (they never see the end result). However, it can't just be removed from that method, because it is called from many places, so maybe it needs another parameter to tell it to skip the capability check - or maybe it should be a separate method, or maybe fill_from_queue() should do its own query directly...

As a manual fix for groups already in this situation, go to Administration > Administrate groups (as a teacher/manager/admin), click the "Resize" (pencil) icon next to the group size, and press Enter to save it without actually changing the group size. This calls resize_group(), which calls fill_from_queue() again, this time as a user that does have permission to run it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions