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

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

    // limit list to users with some role only
    if ($role) {
        $wheres[] = "u.id 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(u.id) $from $where", $params);
    return $totalcount;
}

0 comments