Enrolment plugins 2.0

Jump to: navigation, search


The enrolment plugin system in Moodle has evolved over a long period spanning the time before and after the configurable roles system was introduced in Moodle 1.7. Despite the evolution, it is showing its age and it is probably time for a more fundamental rethink.

This page is a tool to help that thinking. There is no guarantee that anything will happen for Moodle 2.0. There are plenty of other things on the roadmap with higher priority.

Problem description

  • very poor performance - course participation based on capability is in many cases extremely slow, it can not compare to enrolments described as simple SQL
  • enrolment approximation - gradebook roles hack, statistics enrolment hack, group membership hacks, etc.
  • missing separation of entering of course and participation in course - the all powerful course:view capability is not flexible enough
  • all enrolment plugins share the same configuration fields - configuration for each enrolment plugin must be separate (ex. one course cost + currency is not enough)
  • single instances of enrolment plugin in one course - ex: 3x paypal with different role for each amount
  • negative legacy guest capability - get access in one role overrides all other roles, you can not undo guest access once you get it from parent context
  • problematic hardcoded guest access logic - guest access to course
  • incomplete metacourse implementation - might be replaced by global groups and enrolment improvements
  • missing global groups - current coding attempts are either very slow or incomplete
  • undefined handling of user data after unenroling - should be purged for performance reasons
  • not possible to easily suspend or delay course access while keeping roles+caps - role tables can not handle this, it would be order of magnitude slower and not flexible enough, in general we need ip/time/xxx based course access restriction
  • archiving of courses not implemented

Use cases

  1. [Conceptual] In all sorts of places, we need to distinguish people who can get into the course and look around (guests, admins, inspectors, ...) from people who are actually participants in the course (students and teachers).
  2. [Conceptual] We need to distinguish users in the course who appear in the gradebook, or whose results appear in the quiz reports.
  3. Teacher wants each student to pay $1000 through some billing system before they can join a course.
  4. Teacher offers a time limited period (let us say one week) of free access to a course. After this free demo, student has to pay to stay enrolled in the course. Compare with shareware licences.
  5. Teacher wants student to enter a password before they can join a course, and depending which password they enter, they may get put in different groups.
  6. Teacher wants to allow students to self-register for a course, but only within a certain time period.
  7. Teacher wants students to self-register in Calculus 201, but only if they have completed Maths 101.
  8. Teacher wants to remove student's access at the end of the course, but still wants to be able to go back later and look at the gradebook data.
  9. Teacher wants a manual way to to unenrol a user, even if they have self-registered, and prevent them re-registering.
  10. If the teacher mis-clicks and unenrols the wrong user, they want to be able to immediately re-enrol them, without any data being lost.
  11. Teacher wants a way to automatically unenrol users who do not actively participate for 30 days.
  12. Admin wants to automatically synchronise enrolments with some external database or application. (While still having some manually created role assignments in the system.)
  13. Admin does not want teachers to be able to unenrol students that have been added by the synchronise plugins, but does want them to be able to remove students they have added manually.
  14. Metacourses - automatically enroling in one course should enrol you in a parent course - do we need to keep this working the way it does now? or would an alternative solution be acceptable?
  15. Admin wants anyone who is a teacher in any course to automatically get a special role at site level, so teachers in any course can get some site-level capabilities.
  16. When backing up and restoring a course, need some control which enrolments are included. (Need specific details.)
  17. Information about enrolment must automatically appear in course listings (but only to unenroled users?) (Do we really need this automatically generated, can't teachers put whatever they like in the coures description?)
  18. [Technical] When analysing data to generate reports like this, we need to be able to do a simple join in SQL to work out which users should be included in the report.
  19. [Technical] Data specific to certain enrolment methods (e.g. price, password) should not be stored in the course table.
  20. [Technical] Some of this need to be configured at the site level, others at course level. (And would we ever want things to happen at category or activity level? What about automatic enrolment of parents?)
  21. [Technical] Whether guests or logged in users are allowed into a course as guests should really only be a matter of setting overrides on the respective role. This should not be stored separately (irrespective of what the interface for setting these options are).
  22. [Technical] Configuring enrolment options for your course will either by on the course settings page, or on a separate tab next to Course settings and Assign roles.
  23. Teacher wants to assign a 'group of students' at a time (this group would exist at global context and might be populated automatically by an external system)

(Any role mentioned in the above text is mentioned informally, by way of motivating the feature. In the actual system, each feature should work with any role.)

Solution 1

My (Tim's) proposed solution would be this (in fact, I don't think it is a very big change from what we have now):

  • The current state of who is enrolled in which course is stored indirectly via role assignments (as at present).
  • A user is deemed to be a participant in a course if they have the (new) capability moodle/course:participate in that course context. If a user does not have this capability, then they may still be allowed into the course if they have the (existing) moodle/course:view capability. By default, Student, Teacher and Non-editing teachers would have the participate capability. Admin, Course creator and Guest? would get course:view.
  • A user would appear in the gradebook if they have the (new) capability moodle/course:begraded. By default, only Students would have this capability.
  • Enrolment plugins are just ways of creating (or deleting) role assignments, and hence letting people into courses.
  • There should be hooks, when a user tries to get into a course they are not a participant of, for enrolment plugins to either let the user in silently by creating a role assignment, or by displaying some UI (like ask for a password or cash), or giving the option to go in as a guest.
  • Alternatively, or as well, enrolment plugins can do things on cron, or when triggered by the events API.
  • Enrolment plugins will have site-wide configuration, so administrators can control which plugins are active for the site, and set their options.
  • Enrolment plugins will also have course-specific configuration, to control which plugin(s) apply to that course, and set any per-course options.
  • To help with reporting and performance, we will make a new table course_participants_cache with columns id, contextid, userid, isparticipant, isgraded. That caches, for each context, or perhaps just each course context and each user, the results of has_capability for the two capabilities moodle/course:participate and moodle/course:begraded (A row will only be included if either isparticipant or isgraded is true.) This is automatically kept up to date whenever roles information changes. (Should that be contextid or courseid?).
  • Extra information will be displayed on the manual Assign roles page and in the Participants list, so you can see which enrolment plugin was responsible for enrolling each student, and information about timed enrolments. (So, for example, you don't end up unenrolling a student who has paid a lot of money to enrol themselves.)

Solution 2

More similar to 1.6 style enrolments, it would be possible to use SQL only to find all course members.

New course_participants table

  • Stores all users who actually participate in the course (ie members of the course)
  • start date, end date - allow specification of past, current and future enrolments/membership/participation
  • multiple entries allowed - different plugins or different periods
  • replaces hidden role assignments
  • when user is unenroled (no more past/future/present entries in this table) user specific info is deleted from course (group membership, grades, subscriptions, choices, etc.)
  • user posts (forum, glossary, database) are purged manually using course reset - new feature purge/anonymize posts by not-enrolled users or new manual user purge feature

Redefined moodle/course:view capability

  • course:view will means user may enter course without enrolment (course participation)
  • course_participation entry means user participates in course - is visible by other users, participates in activities like choice, assignment
  • if user does not have course:view course_participants table is used to determine if entering of course allowed
Be careful Petr: Suppose we want all users to have guest access to all courses by default, and so we change Logged in user role to have moodle/course:view. Then, with what you say above, no-one would participate in any course. I think that course_participants should have higher priority than moodle/course:view. (Actually, no, I still think that moodle/course:_participate capability is the right solution, but that is another argument.)--Tim Hunt 20:44, 20 February 2009 (CST)

Remove direct checking of legacy:guest capability

  • course:view without the enrolment entry means guest and also manager/supervisor access - no need for hidden assignments any more
  • isguest() replaces by isguestuser() or has course:view/require login check

New enrolment_instance table

  • specifies enrolments plugins enabled in the course
  • plugin instance disable option - users can not enter course
  • when plugin instance deleted - all enrolments are moved
  • multiple instances of the same type allowed
  • each instance enrols into one role - course default or custom

Enrolment plugins

New types of plugins:

  • temporary guest enrolment plugin - allows entering of guest or real not-enrolled users, grants course:view temporarily; option for password protected access
  • user enrolment - with or without a password (finally different from the guest access)
  • group/grouping enrolment - password or manual selection of group
  • global group enrolment plugin - enrols users of selected global groups into course and syncs global groups with course groups

New groups_global table

  • stores global groups defined at site or course category level
  • used in global groups enrolment plugin
  • global groups used when selection of several users needed - course assignment, group membership, manual enrolment, etc. - the selected users are not linked/synchronised later

Benefits

  • much faster and a lot of room for even more performance improvements - mostly because we can use SQL to narrow many types of queries
  • simplified course enrolment UI
  • easy implementation of global groups
  • possible solution of all guest problems everywhere
  • very easy to implement delayed/suspended/timed/conditional course access - no need to fiddle with roles any more
  • removed problematic assignments of Student role at category or system level
  • simplified definition of course managers

Potential problems

  • migration of existing meta course data
  • keeping course_participants up to date when adding/removing people+courses at category level.

Detailed design

Will only be done later, if we get agreement on the use cases and solution overview.

List of related tracker issues

see MDL-17949

See also