Note: You are currently viewing documentation for Moodle 1.9. Up-to-date documentation for the latest stable version is available here: Groups documentation for module developers.

Obsolete:Groups documentation for module developers

From MoodleDocs

Groups in Moodle for developers

IMPORTANT: This documentation does not refer to current versions of Moodle and is here at the moment purely in order to obtain comments. Descriptions of how groups work refer to how they hopefully work not how they will work now! This document is also written in the present tense even though it doesn't refer to the current version of Moodle. This is so I don't have to go through and change it all in a month or two's time.

How groups work in Moodle

It is possible to have groups of users in Moodle. A person with the right permissions (generally an editting teacher or admin) can create groups for a course and add and remove users from groups. They can also create sets of groups for the course which we'll refer to as 'groupings'. Groups that belong to the course can be added to and removed from any of the groupings that have been created for the course.

If you haven't seen the interface for creating groupings and groups, I'd recommend you go to a course in your installation of Moodle for which you have edit access and which has some participants and follow the Groups link and take a look (note: you can't currently do this obviously as the code isn't released yet!).

Once there is at least one grouping created for a course, when an editor adds an instance of a module they may if they wish assign one of the groupings for the course to use with that instance of the module. A user who is not in a group for a grouping assigned will not be able to see that the instance of the module exists. It is also possible for the editor to specify a grouping to use for everything for the course - this is set up in the course settings.

Each group and grouping must 'belong' to at least one course (it's possible for them to belong to more than one course, but there's no user interface to let you do this easily at the moment). Both teachers and students can belong to groups and a user can belong to more than one group. It is also possible for a group to belong to more than one grouping.

There is a choice of various permission settings for a grouping - for instance you can specify that students may both view and contribute to the group of which they are a member but only view groups of which they are not members. In time these settings wil hopefully be superceded by an extension of the roles and permission system used elsewhere in Moodle, but at the moment they are independent. The main types of permission that a user can have for a particular group are 'student view', 'student contribute', 'teacher view' and 'teacher contribute', with it being up to modules to decide how to interpret these. As we have seen, a user does not need to be a member of a group to have a particular permission type for that group.

As well as modules, there are also some blocks and global features such as blogs and the calendar that use groups in certain ways. We'll come to those later.

It is obviously good if modules support groups in the ways that users expect! This document is here to try and help you do that - if anything isn't clear, you have questions or can think of improvements to how groups work in Moodle, please post on the Groups forum on moodle.org.

How does this differ from the way groups previously worked?

The biggest difference is that previously it was only possible to have one set of groups for a course. All activities for a course had to use the same set of groups. This is the main reason that the API needed to change.

Also, previously, for a course with groups, there were two groups modes - separate and visible. With separate groups, students could not see groups to which they did not belong, whereas with visible groups they could see groups to which they did not belong but not contribute to them. This caused a great deal of confusion when it came to teachers belonging to groups and also led to lots of really horrible logic in module code trying to work out who could view or contribute to an activity. This is why the separate/visible groups modes have been replaced by a more granular and flexible permissions system.

Another big difference that isn't visible is there are now tables in the database for course_groups and courses_groupings, whereas previous the groups table had a courseid column. This made it very difficult to use the same group for more than one course. This should now be much easier. However this obviously affects code that used to access the groups table directly.

There are also improvements to the user interface for creating groups, though these aren't specifically relevant to module developers.

How should modules support groups?

There are two main ways a module might need to support groups. There may of course be other more unusual ways in which your module should supports groups, but these should hopefully be the most common ones. The important thing is to think about how people would expect your module to behave if they chose to use groups for it.

From a student's point of view

From a student's point of view, groups are generally used as a way to enable parallel versions of the same activity with different groups of students e.g you might want a separate forum or wiki for each group. If your module is collaborative in any way (which includes the ability to view the existence of other students or their contributions) then you need to make sure that this is supported.

As well as the obvious views of activities being separated, you will need to make sure that things like searches return the correct results and that teachers can view the correct groups. You may also need to make a decision as to which teacher activity is part of the setup of the activity so is the same for every group and needs to be performed only once, and which teacher activity is the contribution after the activity has started and so is different for each group.

In general if you module needs to support groups in this way you will find that the database table(s) where you store the students' contributions will probably need an extra 'groupid' column, for instance the forum table has a groupid column.

From a teacher's point of view

From a teacher's point of view, groups are generally used to manage different groups of students. For instance there may be several teachers on a course each assigned to one or more groups of students who mark the work for the groups of students that have been assigned to them but shouldn't be able to mark the work of the other groups. A single teacher may also want to be able to view marks for students by group when they teach the same material to two different classes. In general, if your module enables teachers to somehow view students' contribution, then you need to provide this type of support. You can usually do this by checking which students are in which group rather than needing to alter the module's database tables in any way.

Dealing with users in more than one group

Although users may be belong to more than one group, most of the time you can use the groups library for modules to deal with this rather than having to worry about this yourself. There will be more about this in the next section. The time you will probably find that you need to worry about this is when for instance you are doing a search for contributions that a particular student is allowed to view. In this case you will need to look for contributions for all the groups rather than just one group.

The groups library for modules

The functions at your disposal can be found in course/groups/lib/modulelib.php - go and have a quick look at it now. (Again you can't yet, but look here at the Groups API for modules instead) Here are some examples of common ways in which you might want to use the functions in it.

1) Present a user with a page containing the right information for one of the groups that they belong to including a selector to see the equivalent page for any other groups that they belong to. e.g. present a user with a list of discussion for a group they belong to.

if (groups_m_uses_groups($cmid)) {
    $permissiontype = GROUPS_STUDENT_CONTRIBUTE;
    groups_m_print_group_selector($cmid, $urlroot, $permissiontype);
    $currentgroupid = groups_m_get_selected_group($cmid, $permissiontype);
    // This is your function that you've written. 
    do_whizzy_module_stuff_for_group($cmid, $currentgroupid); 
} else {
    // Do whatever you'd normally do
}

2) Present a user with search results only for the groups that they are allowed to view.

if (groups_m_uses_groups($cmid)) {
    $permissiontype = GROUPS_VIEW;
    $groupids = groups_m_get_groups_for_user($cmid, $permissiontype);
    // You might want the search funtion to check group permissions too to be 
    // on the safe side. 
   get_module_search_results_for_groups($groupids, $maybesomeotherparameters);
} else {
    // Do whatever you'd normally do
}

3) Get a list of users which a teacher should be able to mark work

if (groups_m_uses_groups($cmid)) {
    $permissiontype = GROUPS_TEACHER_CONTRIBUTE;
    groups_m_print_group_selector($cmid, $urlroot, $permissiontype);
    $groupid = groups_m_get_selected_group($cmid, $permissiontype);
    $userids = groups_m_get_members($groupid);
} else {
    // Get your userids the normal way
}
// Do whatever you'd normally do with the userids. 

It is still ok to use inner joins on the groups_members table in the database for this type of functionality as obviously this is sometimes required for performance reasons, but make sure you keep your code that queries the database clearly separated from your other code.

Support for legacy code

The following functions should still be supported but are deprecated:

get_groups user_group ismember get_group_users get_group_students get_group_teachers add_user_to_group mygroupid groupmode set_current_group get_current_group get_and_set_current_group setup_and_print_groups

Where appropriate, if a grouping has been specified in the course setting for use for all activities that grouping will be used in what was previously 'separate groups' mode. If no such grouping has been specified then the first grouping created for the course that still exists will be used, again in separate groups mode. If you want better support than this, then I'm afraid you will need to update the code for your module!

Accessing the groups_members table directly should still work (although it is not recommended unless you need to do an inner join on it for performance reasons). Directly accessing the groups table may not work because the course column has been removed.

The groupid argument in the function search_users from datalib.php will still work, but will only give members of a group, not those with a specific permission.

Blocks and other special cases

There is an essentially identical library for blocks as for modules, only all the _m_'s in the function names are replaced by _b_'s.

At the moment there is no standard way to set the grouping for a block and most blocks don't need to use groups. If you want to create a way for someone to set up a grouping for your block then you will need to do this yourself using the functions in the other parts of the groups library (under course/groups/lib/) but ask if you need help. There is a new column in the block_instance table called groupingid that you will need to set using the function groups_set_grouping_for_block_instance. If a grouping is set for all activities for a course then this will get automatically set however.

There are currently two 'global' features in the Moodle core - blogs and the calendar - a quick word on those in case anyone has plug-ins that provide similar global features.

Calendar - with the calendar a teacher can set group events when they are within a course, so basically all they need to do is get all the groups for the course that a teacher has a particular permission for. Then when displaying calendar entries to users, need to know which groups a particular has view permission for across all courses though it's a tiny bit more complicated that this because a grouping can be used for more than one course and someone may be a student on one course and a teacher on another.

Blog - It's possible for the admin to set a blog option that makes blogs view access group level. This means that users can only see blogs of people that they share a group with for some course - there's a function provided in one of the main groups libraries to find out if two users share a group. I'm guessing that you're mostly only wanting to use this with installations with a very small number of teachers and at some point global groups will get used here instead.

At the moment there is generally no general support for global features, but this will hopefully come!

Some rationale

I'll probably add stuff in here as it comes up :-)

Why doesn't this fit in with roles and permissions?

Mostly at the time I started doing this development the roles and permission code wasn't available yet! The changes to roles and permissions are big and the changes needed to fit in with them properly need some thought and would be even more massive than they currently are. It seemed better to get the main improvements to groups in first and give the roles and permissions code a bit of time to settle. It would be nice if they are integrated sensible eventually.

Why do I have to deal separately with the case where the module uses groups and the case where it doesn't? Isn't there a clever way to do this so I don't have to?

Yes, but I wanted to try and keep people's code fairly readable and make it as easy as possible to shift current over. In practice you shouldn't really have too much extra code this way anyhow - you can always write functions with a groupid argument that defaults to false.

Future plans? (Things I'd like to do or you can do for me!)

In no particular order:

  • Bug fixing I guess :-)
  • Global groups - I want it to be possible to set up groupings for course 1 and for these to be visible for all course on the site, but not editable or deletable. I think this code should actually be quite easy to write now and I might even do it before this code is put in, just haven't done it yet.
  • A nicer user interface (that doesn't break the back button :-) Ajax separates the back and front end of the code really well, so if anyone has good ideas on this, it should be quite easy for someone else to do without having to know how the internals of the groups code work.
  • Integration with roles and permissions
  • Sign up sheets for groups
  • Proper support for blocks and global features.
  • A way for modules and blocks to declare whether they support groups or not.
  • Putting in search_users functionality for group permissions as well as just members of groups.
  • Cool ways to set up groups automatically for particular pedagogical reasons - things like minimising overlap with groups in another grouping, creating groups just from the users all in another group and creating groups which merge pairs of groups from another grouping.