What is the right way of getting all course users ?

What is the right way of getting all course users ?

by Nicolas Dunand -
Number of replies: 9
Picture of Core developers Picture of Plugin developers
Hello all,

I'm currently developing two Moodle blocks, which have to list all students of the current course. I've been using the

get_course_students(courseid);

in 1.6 for a while. However we're now migrating towards Moodle version 1.8 and I saw that this function is now deprecated. So in order not to lose compatibility in further versions I tried to change my code, and used

$context = get_context_instance();
get_role_users (5, $context);

or

get_users_by_capability ($context, "moodle/legacy:student");

I hoped to get an array of objects containing my students, but no way. I guess there's something I don't get with this new roles and context system, but couldn't find any help in the documentation.

If anyone has an idea on how to get over this, it would be greatly appreciated.


Nicolas

Average of ratings: -
In reply to Nicolas Dunand

Re: What is the right way of getting all course users ?

by Sam Chaffee -
Picture of Core developers
Hi Nicolas,

I've been using the capability 'moodle/course:view' to get the participants of a course. That will return all participants in a course. This documentation describes some of the capabilities. Because the role system allows more flexibility than 'students' or 'teachers' there is no way to find them. Depending upon what your block does, you may want to create new capabilities for it. The procedure will be a little different for a block than is described in the docs, but you can look to the rss_client block as an example.

Hope that helps.

Sam
In reply to Sam Chaffee

Re: What is the right way of getting all course users ?

by Nicolas Dunand -
Picture of Core developers Picture of Plugin developers
Hi Sam,

Thanks for the quick answer. It seems that the 'moodle/course:view' is more or less what I need, except that I'd have to take out the tutors and admin out. It's funny, because I can describe my students as "students" when creating accounts and adding their roles to the course, but there seems to be no simple way to get them listed afterwards...

I'm however having trouble with the 'context' : I'm unable to use the right context in

$users = get_users_by_capability($context, "moodle/course:view");
(the context here should be the course in which the block is instanciated)

If I try to get the context this way :

$context = get_context_instance();

i'm not getting any users except the site admin. So I tried and forced the right context by using

$context = get_context_instance_by_id($id);

entering manually $id by looking in the SQL tables sad but this is no solution as I can't hard-code the context ID.

So I would like to be able to get the context of the course ... how can I do that ? Sorry but I searched throughout the site and couldn't find any place where the contexts are explained.


Nicolas
In reply to Nicolas Dunand

Re: What is the right way of getting all course users ?

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
get_context_instance($courseid, CONTEXT_COURSE) should do it. Look at the PHP doc comment about where get_context_instance is defined in lib/accesslib.php if you need more information.
In reply to Tim Hunt

Re: What is the right way of getting all course users ?

by Nicolas Dunand -
Picture of Core developers Picture of Plugin developers
Hi Tim !

Thanks for your answer ; actually, the correct syntax is :
get_context_instance(CONTEXT_COURSE, $courseid)

Thanks a lot for your help.

Nicolas
In reply to Nicolas Dunand

Re: What is the right way of getting all course users ?

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers
I was going to tell you how to use get_context_instance but Tim got there first. However I just wanted to say that in my opinion you were right first time with the solution to the problem - it's very rare that you actually want a list of everyone who can view the course, because that includes all the admins and crap. In your case if you just want students it's quite easy:

$context = get_context_instance(CONTEXT_COURSE, $course->id);
$roleid=get_field('role','id','name','student');
$answer=get_role_users ($roleid, $context);

There are some big caveats with this approach, though. First, note the bold line! (Which I typed without checking the names of the fields so it might be slightly wrong, but basically, make sure you never hard-code a role ID like with '5' in your example as they can be different on different installs, whereas you can more rely on the short names.)

The other obvious caveat is that this won't work for sites that don't use the 'student' role. That's cool if you are doing it just for your own use and you know you do use it.

If you're not, one solution is to set up a global preference that provides a UI for people to select the role(s) which apply in this case (and make this default to 'student').

But another, perhaps better, alternative is to add a new capability as part of your block - sort of a 'be-counted-as-a-student-in-my-block' capability. You can then assign that capability only to students and not to anyone else. Then you can use get_users_by_capability and it should all just work, without having to do any special user interface for configuration (and you can easily assign it to two roles if you decide tutors need to be included as well, or something). When checking the capability, you have to remember to set 'doeverything' to false or it'll include admins again... (IMO the 'doeverything' setting was a big mistake that complicates the role system and should be got rid of... oh well.)

We use this approach in one place, it works.

--sam
In reply to sam marshall

Re: What is the right way of getting all course users ?

by Nicolas Dunand -
Picture of Core developers Picture of Plugin developers
Hi Sam,

and thanks for these more in-depth explanations. It's actually much more simple that the one I came out with (i.e. listing all users having course viewing capability, then removing admins etc.).

For the record, the right syntax to get $roleid is :
$roleid = get_field ('role', 'id', 'shortname', 'student');
(my install is in french, so 'shortname' != 'name')

As we only use 'teacher' and 'student' roles on our install, I guess this will do. I can still refine the function later on if needed.

Thanks a lot !


Nicolas
In reply to Nicolas Dunand

Re: What is the right way of getting all course users ?

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
With get_users_by_capability, you can easily exclude admins by passing $doanything=false.
In reply to Nicolas Dunand

Re: What is the right way of getting all course users ?

by Thirot Jean-Luc -
Bonjour Nicolas,

Why you don't copy the code from this page "Attribution des rôles"
admin/roles/assign.php?contextid=2113&roleid=5 ?

Jean-Luc
In reply to Thirot Jean-Luc

Re: What is the right way of getting all course users ?

by Nicolas Dunand -
Picture of Core developers Picture of Plugin developers
Thanks Tim.

And salut Jean-Luc,

good idea, thanks. As my main problem was to dynamically get the ID of my context (i.e. course context in this case) I could have looked in the admin block code, indeed.

Nicolas