Moodle 2: Get number of students in a course

Posted by jason on June 15, 2011, 7:45 p.m.
Tags: moodle php programming web

I searched around and couldn't find anything about getting the # of students in a course in Moodle 2. So I wrote a function to do it. I basically just copy-pasted the needed stuff from the /user/index.php file. Yes, this function is ridiculously long, considering the simple question it's trying to answer.

Anyway, here is the code. Do with it what you will.

 * Function to get the number of students in a given course.
 * @param $courseid int Unique course ID.
 * @return int The number of students in the course.
function get_nstudents($courseid) {
    global $DB;

    $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
    $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
    require_capability('moodle/course:viewparticipants', $context);
    $role = $DB->get_record('role', array('shortname'=>'student'), '*', MUST_EXIST);

    $contextlist = get_related_contexts_string($context);

    list($esql, $params) = get_enrolled_sql($context, NULL, NULL, true);

    $joins = array("FROM {user} u");
    $wheres = array();

    $select = "SELECT, u.username, u.firstname, u.lastname,
            ,,, u.picture,
                      u.lang, u.timezone, u.maildisplay, u.imagealt,
                      COALESCE(ul.timeaccess, 0) AS lastaccess";
    $joins[] = "JOIN ($esql) e ON ="; // course enrolled users only
    // not everybody accessed course yet
    $joins[] = "LEFT JOIN {user_lastaccess} ul ON (ul.userid = AND ul.courseid = :courseid)"; 
    $params['courseid'] = $course->id;

    // performance hacks - we preload user contexts together with accounts
    list($ccselect, $ccjoin) = context_instance_preload_sql('', CONTEXT_USER, 'ctx');
    $select .= $ccselect;
    $joins[] = $ccjoin;

    // limit list to users with some role only
    if ($role) {
        $wheres[] = " IN (SELECT userid FROM {role_assignments} WHERE roleid = :roleid AND contextid $contextlist)";
        $params['roleid'] = $role->id;

    $from = implode("\n", $joins);
    if ($wheres) {
        $where = "WHERE " . implode(" AND ", $wheres);
    } else {
        $where = ""; 

    $totalcount = $DB->count_records_sql("SELECT COUNT( $from $where", $params);
    return $totalcount;