Get course participants details

@param int $courseid  course id
@param array $options options {
'name' => option name
'value' => option value
}
@return array An array of users
343165
public static function get_enrolled_users($courseid, $options = array()) {
        global $CFG, $USER, $DB;

        require_once($CFG->dirroot . '/course/lib.php');
        require_once($CFG->dirroot . "/user/lib.php");

        $params = self::validate_parameters(
            self::get_enrolled_users_parameters(),
            array(
                'courseid'=>$courseid,
                'options'=>$options
            )
        );
        $withcapability = '';
        $groupid        = 0;
        $onlyactive     = false;
        $userfields     = array();
        $limitfrom = 0;
        $limitnumber = 0;
        $sortby = 'us.id';
        $sortparams = array();
        $sortdirection = 'ASC';
        foreach ($options as $option) {
            switch ($option['name']) {
            case 'withcapability':
                $withcapability = $option['value'];
                break;
            case 'groupid':
                $groupid = (int)$option['value'];
                break;
            case 'onlyactive':
                $onlyactive = !empty($option['value']);
                break;
            case 'userfields':
                $thefields = explode(',', $option['value']);
                foreach ($thefields as $f) {
                    $userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
                }
                break;
            case 'limitfrom' :
                $limitfrom = clean_param($option['value'], PARAM_INT);
                break;
            case 'limitnumber' :
                $limitnumber = clean_param($option['value'], PARAM_INT);
                break;
            case 'sortby':
                $sortallowedvalues = array('id', 'firstname', 'lastname', 'siteorder');
                if (!in_array($option['value'], $sortallowedvalues)) {
                    throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $option['value'] . '),' .
                        'allowed values are: ' . implode(',', $sortallowedvalues));
                }
                if ($option['value'] == 'siteorder') {
                    list($sortby, $sortparams) = users_order_by_sql('us');
                } else {
                    $sortby = 'us.' . $option['value'];
                }
                break;
            case 'sortdirection':
                $sortdirection = strtoupper($option['value']);
                $directionallowedvalues = array('ASC', 'DESC');
                if (!in_array($sortdirection, $directionallowedvalues)) {
                    throw new invalid_parameter_exception('Invalid value for sortdirection parameter
                        (value: ' . $sortdirection . '),' . 'allowed values are: ' . implode(',', $directionallowedvalues));
                }
                break;
            }
        }

        $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
        $coursecontext = context_course::instance($courseid, IGNORE_MISSING);
        if ($courseid == SITEID) {
            $context = context_system::instance();
        } else {
            $context = $coursecontext;
        }
        try {
            self::validate_context($context);
        } catch (Exception $e) {
            $exceptionparam = new stdClass();
            $exceptionparam->message = $e->getMessage();
            $exceptionparam->courseid = $params['courseid'];
            throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
        }

        course_require_view_participants($context);

        // to overwrite this parameter, you need role:review capability
        if ($withcapability) {
            require_capability('moodle/role:review', $coursecontext);
        }
        // need accessallgroups capability if you want to overwrite this option
        if (!empty($groupid) && !groups_is_member($groupid)) {
            require_capability('moodle/site:accessallgroups', $coursecontext);
        }
        // to overwrite this option, you need course:enrolereview permission
        if ($onlyactive) {
            require_capability('moodle/course:enrolreview', $coursecontext);
        }

        list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
        $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
        $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)";
        $enrolledparams['contextlevel'] = CONTEXT_USER;

        $groupjoin = '';
        if (empty($groupid) && groups_get_course_groupmode($course) == SEPARATEGROUPS &&
                !has_capability('moodle/site:accessallgroups', $coursecontext)) {
            // Filter by groups the user can view.
            $usergroups = groups_get_user_groups($course->id);
            if (!empty($usergroups['0'])) {
                list($groupsql, $groupparams) = $DB->get_in_or_equal($usergroups['0'], SQL_PARAMS_NAMED);
                $groupjoin = "JOIN {groups_members} gm ON (u.id = gm.userid AND gm.groupid $groupsql)";
                $enrolledparams = array_merge($enrolledparams, $groupparams);
            } else {
                // User doesn't belong to any group, so he can't see any user. Return an empty array.
                return array();
            }
        }
        $sql = "SELECT us.*, COALESCE(ul.timeaccess, 0) AS lastcourseaccess
                  FROM {user} us
                  JOIN (
                      SELECT DISTINCT u.id $ctxselect
                        FROM {user} u $ctxjoin $groupjoin
                       WHERE u.id IN ($enrolledsql)
                  ) q ON q.id = us.id
             LEFT JOIN {user_lastaccess} ul ON (ul.userid = us.id AND ul.courseid = :courseid)
                ORDER BY $sortby $sortdirection";
        $enrolledparams = array_merge($enrolledparams, $sortparams);
        $enrolledparams['courseid'] = $courseid;

        $enrolledusers = $DB->get_recordset_sql($sql, $enrolledparams, $limitfrom, $limitnumber);
        $users = array();
        foreach ($enrolledusers as $user) {
            context_helper::preload_from_record($user);
            if ($userdetails = user_get_user_details($user, $course, $userfields)) {
                $users[] = $userdetails;
            }
        }
        $enrolledusers->close();

        return $users;
    }
242020
public static function get_forums_by_courses($courseids = array()) {
        global $CFG;

        require_once($CFG->dirroot . "/mod/forum/lib.php");

        $params = self::validate_parameters(self::get_forums_by_courses_parameters(), array('courseids' => $courseids));

        $courses = array();
        if (empty($params['courseids'])) {
            $courses = enrol_get_my_courses();
            $params['courseids'] = array_keys($courses);
        }

        // Array to store the forums to return.
        $arrforums = array();
        $warnings = array();

        // Ensure there are courseids to loop through.
        if (!empty($params['courseids'])) {

            list($courses, $warnings) = external_util::validate_courses($params['courseids'], $courses);

            // Get the forums in this course. This function checks users visibility permissions.
            $forums = get_all_instances_in_courses("forum", $courses);
            foreach ($forums as $forum) {

                $course = $courses[$forum->course];
                $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id);
                $context = context_module::instance($cm->id);

                // Skip forums we are not allowed to see discussions.
                if (!has_capability('mod/forum:viewdiscussion', $context)) {
                    continue;
                }

                $forum->name = external_format_string($forum->name, $context->id);
                // Format the intro before being returning using the format setting.
                list($forum->intro, $forum->introformat) = external_format_text($forum->intro, $forum->introformat,
                                                                                $context->id, 'mod_forum', 'intro', null);
                $forum->introfiles = external_util::get_area_files($context->id, 'mod_forum', 'intro', false, false);
                // Discussions count. This function does static request cache.
                $forum->numdiscussions = forum_count_discussions($forum, $cm, $course);
                $forum->cmid = $forum->coursemodule;
                $forum->cancreatediscussions = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
                $forum->istracked = forum_tp_is_tracked($forum);
                if ($forum->istracked) {
                    $forum->unreadpostscount = forum_tp_count_forum_unread_posts($cm, $course);
                }

                // Add the forum to the array to return.
                $arrforums[$forum->id] = $forum;
            }
        }

        return $arrforums;
    }
1078525
public static function get_databases_by_courses($courseids = array()) {
        global $PAGE;

        $params = self::validate_parameters(self::get_databases_by_courses_parameters(), array('courseids' => $courseids));
        $warnings = array();

        $mycourses = array();
        if (empty($params['courseids'])) {
            $mycourses = enrol_get_my_courses();
            $params['courseids'] = array_keys($mycourses);
        }

        // Array to store the databases to return.
        $arrdatabases = array();

        // Ensure there are courseids to loop through.
        if (!empty($params['courseids'])) {

            list($dbcourses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);

            // Get the databases in this course, this function checks users visibility permissions.
            // We can avoid then additional validate_context calls.
            $databases = get_all_instances_in_courses("data", $dbcourses);

            foreach ($databases as $database) {

                $context = context_module::instance($database->coursemodule);
                // Remove fields added by get_all_instances_in_courses.
                unset($database->coursemodule, $database->section, $database->visible, $database->groupmode, $database->groupingid);

                // This information should be only available if the user can see the database entries.
                if (!has_capability('mod/data:viewentry', $context)) {
                    $fields = array('comments', 'timeavailablefrom', 'timeavailableto', 'timeviewfrom',
                                    'timeviewto', 'requiredentries', 'requiredentriestoview', 'maxentries', 'rssarticles',
                                    'singletemplate', 'listtemplate', 'listtemplateheader', 'listtemplatefooter', 'addtemplate',
                                    'rsstemplate', 'rsstitletemplate', 'csstemplate', 'jstemplate', 'asearchtemplate', 'approval',
                                    'manageapproved', 'defaultsort', 'defaultsortdir');

                    foreach ($fields as $field) {
                        unset($database->{$field});
                    }
                }

                // Check additional permissions for returning optional private settings.
                // I avoid intentionally to use can_[add|update]_moduleinfo.
                if (!has_capability('moodle/course:manageactivities', $context)) {

                    $fields = array('scale', 'assessed', 'assesstimestart', 'assesstimefinish', 'editany', 'notification',
                                    'timemodified');

                    foreach ($fields as $field) {
                        unset($database->{$field});
                    }
                }
                $exporter = new database_summary_exporter($database, array('context' => $context));
                $arrdatabases[] = $exporter->export($PAGE->get_renderer('core'));
            }
        }

        $result = array();
        $result['databases'] = $arrdatabases;
        $result['warnings'] = $warnings;
        return $result;
    }
418588
public static function get_least_proficient_competencies_for_course($courseid, $skip = 0, $limit = 0) {
        global $DB;

        $fields = competency::get_sql_fields('c', 'c_');
        $params = array('courseid' => $courseid);
        $sql = 'SELECT ' . $fields . '
                  FROM (SELECT cc.competencyid, SUM(COALESCE(ucc.proficiency, 0)) AS timesproficient
                          FROM {' . course_competency::TABLE . '} cc
                     LEFT JOIN {' . self::TABLE . '} ucc
                                ON ucc.competencyid = cc.competencyid
                               AND ucc.courseid = cc.courseid
                         WHERE cc.courseid = :courseid
                      GROUP BY cc.competencyid
                     ) p
                  JOIN {' . competency::TABLE . '} c
                    ON c.id = p.competencyid
              ORDER BY p.timesproficient ASC, c.id DESC';

        $results = $DB->get_records_sql($sql, $params, $skip, $limit);

        $comps = array();
        foreach ($results as $r) {
            $c = competency::extract_record($r, 'c_');
            $comps[] = new competency(0, $c);
        }
        return $comps;
    }
1044320
public function getUserGroups(string $userId, array $options = []): array
    {
        $query = $this->find('list', [
            'keyField' => 'id',
            'valueField' => 'name'
        ]);
        $query->matching('Users', function ($q) use ($userId) {
            return $q->where(['Users.id' => $userId]);
        });
        $query->applyOptions($options);

        return $query->toArray();
    }
718154
public function participantsUserIds($userId = null)
    {
        $users = $this->participants()->select('user_id')->get()->map(function ($participant) {
            return $participant->user_id;
        });

        if ($userId) {
            $users->push($userId);
        }

        return $users->toArray();
    }
552341
public static function get_concepts($courseid) {
        list($glossaries, $concepts) = self::get_course_concepts($courseid);
        list($globalglossaries, $globalconcepts) = self::get_global_concepts();

        foreach ($globalconcepts as $gid => $cs) {
            if (!isset($concepts[$gid])) {
                $concepts[$gid] = $cs;
            }
        }
        foreach ($globalglossaries as $gid => $name) {
            if (!isset($glossaries[$gid])) {
                $glossaries[$gid] = $name;
            }
        }

        return array($glossaries, $concepts);
    }
167260
public static function get_activities_completion_status($courseid, $userid) {
        global $CFG, $USER;
        require_once($CFG->libdir . '/grouplib.php');

        $warnings = array();
        $arrayparams = array(
            'courseid' => $courseid,
            'userid'   => $userid,
        );

        $params = self::validate_parameters(self::get_activities_completion_status_parameters(), $arrayparams);

        $course = get_course($params['courseid']);
        $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
        core_user::require_active_user($user);

        $context = context_course::instance($course->id);
        self::validate_context($context);

        // Check that current user have permissions to see this user's activities.
        if ($user->id != $USER->id) {
            require_capability('report/progress:view', $context);
            if (!groups_user_groups_visible($course, $user->id)) {
                // We are not in the same group!
                throw new moodle_exception('accessdenied', 'admin');
            }
        }

        $completion = new completion_info($course);
        $activities = $completion->get_activities();

        $results = array();
        foreach ($activities as $activity) {

            // Check if current user has visibility on this activity.
            if (!$activity->uservisible) {
                continue;
            }

            // Get progress information and state (we must use get_data because it works for all user roles in course).
            $activitycompletiondata = $completion->get_data($activity, true, $user->id);

            $results[] = array(
                       'cmid'          => $activity->id,
                       'modname'       => $activity->modname,
                       'instance'      => $activity->instance,
                       'state'         => $activitycompletiondata->completionstate,
                       'timecompleted' => $activitycompletiondata->timemodified,
                       'tracking'      => $activity->completion,
                       'overrideby'    => $activitycompletiondata->overrideby,
                       'valueused'     => core_availability\info::completion_value_used($course, $activity->id)
            );
        }

        $results = array(
            'statuses' => $results,
            'warnings' => $warnings
        );
        return $results;
    }
7130
protected function get_all_courses($limitcourseids) {
        global $DB;

        if ($limitcourseids) {
            list ($coursesql, $courseparams) = $DB->get_in_or_equal($limitcourseids);
            $coursesql = 'id ' . $coursesql;
        } else {
            $coursesql = '';
            $courseparams = [];
        }

        // Get courses using the same list of fields from enrol_get_my_courses.
        return $DB->get_records_select('course', $coursesql, $courseparams, '',
            'id, category, sortorder, shortname, fullname, idnumber, startdate, visible, ' .
            'groupmode, groupmodeforce, cacherev');
    }
505211
public static function count_competencies($courseid) {
        global $DB;

        $sql = 'SELECT COUNT(comp.id)
                  FROM {' . self::TABLE . '} coursecomp
                  JOIN {' . competency::TABLE . '} comp
                    ON coursecomp.competencyid = comp.id
                 WHERE coursecomp.courseid = ? ';
        $params = array($courseid);

        $results = $DB->count_records_sql($sql, $params);

        return $results;
    }
122642
protected function get_sample_courseid($sampleid) {
        global $DB;

        if (empty($this->samplecourses[$sampleid])) {
            $course = enrol_get_course_by_user_enrolment_id($sampleid);
            $this->samplecourses[$sampleid] = $course->id;
        }

        return $this->samplecourses[$sampleid];
    }
591967
public static function get_choices_by_courses($courseids = array()) {
        global $CFG;

        $returnedchoices = array();
        $warnings = array();

        $params = self::validate_parameters(self::get_choices_by_courses_parameters(), array('courseids' => $courseids));

        $courses = array();
        if (empty($params['courseids'])) {
            $courses = enrol_get_my_courses();
            $params['courseids'] = array_keys($courses);
        }

        // Ensure there are courseids to loop through.
        if (!empty($params['courseids'])) {

            list($courses, $warnings) = external_util::validate_courses($params['courseids'], $courses);

            // Get the choices in this course, this function checks users visibility permissions.
            // We can avoid then additional validate_context calls.
            $choices = get_all_instances_in_courses("choice", $courses);
            foreach ($choices as $choice) {
                $context = context_module::instance($choice->coursemodule);
                // Entry to return.
                $choicedetails = array();
                // First, we return information that any user can see in the web interface.
                $choicedetails['id'] = $choice->id;
                $choicedetails['coursemodule'] = $choice->coursemodule;
                $choicedetails['course'] = $choice->course;
                $choicedetails['name']  = external_format_string($choice->name, $context->id);
                // Format intro.
                list($choicedetails['intro'], $choicedetails['introformat']) =
                    external_format_text($choice->intro, $choice->introformat,
                                            $context->id, 'mod_choice', 'intro', null);
                    $choicedetails['introfiles'] = external_util::get_area_files($context->id, 'mod_choice', 'intro', false,
                                                                                    false);

                if (has_capability('mod/choice:choose', $context)) {
                    $choicedetails['publish']  = $choice->publish;
                    $choicedetails['showresults']  = $choice->showresults;
                    $choicedetails['showpreview']  = $choice->showpreview;
                    $choicedetails['timeopen']  = $choice->timeopen;
                    $choicedetails['timeclose']  = $choice->timeclose;
                    $choicedetails['display']  = $choice->display;
                    $choicedetails['allowupdate']  = $choice->allowupdate;
                    $choicedetails['allowmultiple']  = $choice->allowmultiple;
                    $choicedetails['limitanswers']  = $choice->limitanswers;
                    $choicedetails['showunanswered']  = $choice->showunanswered;
                    $choicedetails['includeinactive']  = $choice->includeinactive;
                }

                if (has_capability('moodle/course:manageactivities', $context)) {
                    $choicedetails['timemodified']  = $choice->timemodified;
                    $choicedetails['completionsubmit']  = $choice->completionsubmit;
                    $choicedetails['section']  = $choice->section;
                    $choicedetails['visible']  = $choice->visible;
                    $choicedetails['groupmode']  = $choice->groupmode;
                    $choicedetails['groupingid']  = $choice->groupingid;
                }
                $returnedchoices[] = $choicedetails;
            }
        }
        $result = array();
        $result['choices'] = $returnedchoices;
        $result['warnings'] = $warnings;
        return $result;
    }
1079954
public static function get_by_courseid($courseid) {
        global $DB;

        $params = array(
            'courseid' => $courseid
        );

        $settings = new static(null, (object) $params);
        if ($record = $DB->get_record(self::TABLE, $params)) {
            $settings->from_record($record);
        }

        return $settings;
    }
733575
public static function count_competencies_in_course($courseid) {
        $params = self::validate_parameters(self::count_competencies_in_course_parameters(), array(
            'id' => $courseid,
        ));

        self::validate_context(context_course::instance($params['id']));

        return api::count_competencies_in_course($params['id']);
    }
862512
public static function get_course_enrolment_methods($courseid) {
        global $DB;

        $params = self::validate_parameters(self::get_course_enrolment_methods_parameters(), array('courseid' => $courseid));
        self::validate_context(context_system::instance());

        $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST);
        if (!core_course_category::can_view_course_info($course) && !can_access_course($course)) {
            throw new moodle_exception('coursehidden');
        }

        $result = array();
        $enrolinstances = enrol_get_instances($params['courseid'], true);
        foreach ($enrolinstances as $enrolinstance) {
            if ($enrolplugin = enrol_get_plugin($enrolinstance->enrol)) {
                if ($instanceinfo = $enrolplugin->get_enrol_info($enrolinstance)) {
                    $result[] = (array) $instanceinfo;
                }
            }
        }
        return $result;
    }
395701
public static function get_user_administration_options($courseids) {
        global $CFG;
        require_once($CFG->dirroot . '/course/lib.php');

        // Parameter validation.
        $params = self::validate_parameters(self::get_user_administration_options_parameters(), array('courseids' => $courseids));
        $courseoptions = array();

        list($courses, $warnings) = external_util::validate_courses($params['courseids'], array(), true);

        if (!empty($courses)) {
            foreach ($courses as $course) {
                $adminoptions = course_get_user_administration_options($course, $course->context);
                $options = array();
                foreach ($adminoptions as $name => $available) {
                    $options[] = array(
                        'name' => $name,
                        'available' => $available,
                    );
                }

                $courseoptions[] = array(
                    'id' => $course->id,
                    'options' => $options
                );
            }
        }

        $result = array(
            'courses' => $courseoptions,
            'warnings' => $warnings
        );
        return $result;
    }
1276745
public static function list_course_competencies($courseid) {
        global $PAGE;

        $params = self::validate_parameters(self::list_course_competencies_parameters(), array(
            'id' => $courseid,
        ));

        $coursecontext = context_course::instance($params['id']);
        self::validate_context($coursecontext);

        $output = $PAGE->get_renderer('core');

        $competencies = api::list_course_competencies($params['id']);
        $result = array();

        $contextcache = array();
        $helper = new performance_helper();
        foreach ($competencies as $competency) {
            $context = $helper->get_context_from_competency($competency['competency']);
            $exporter = new competency_exporter($competency['competency'], array('context' => $context));
            $competencyrecord = $exporter->export($output);
            $exporter = new course_competency_exporter($competency['coursecompetency']);
            $coursecompetencyrecord = $exporter->export($output);

            $result[] = array(
                'competency' => $competencyrecord,
                'coursecompetency' => $coursecompetencyrecord
            );
        }

        return $result;
    }