Get all concepts that should be linked in the given course.
@param int $courseid
@return array with two elements - array of glossaries and concepts for each glossary
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);
    }
348097
public static function get_scorms_by_courses($courseids = array()) {
        global $CFG;

        $returnedscorms = array();
        $warnings = array();

        $params = self::validate_parameters(self::get_scorms_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 scorms in this course, this function checks users visibility permissions.
            // We can avoid then additional validate_context calls.
            $scorms = get_all_instances_in_courses("scorm", $courses);

            $fs = get_file_storage();
            foreach ($scorms as $scorm) {

                $context = context_module::instance($scorm->coursemodule);

                // Entry to return.
                $module = array();

                // First, we return information that any user can see in (or can deduce from) the web interface.
                $module['id'] = $scorm->id;
                $module['coursemodule'] = $scorm->coursemodule;
                $module['course'] = $scorm->course;
                $module['name']  = external_format_string($scorm->name, $context->id);
                list($module['intro'], $module['introformat']) =
                    external_format_text($scorm->intro, $scorm->introformat, $context->id, 'mod_scorm', 'intro', null);
                $module['introfiles'] = external_util::get_area_files($context->id, 'mod_scorm', 'intro', false, false);

                // Check if the SCORM open and return warnings if so.
                list($open, $openwarnings) = scorm_get_availability_status($scorm, true, $context);

                if (!$open) {
                    foreach ($openwarnings as $warningkey => $warningdata) {
                        $warnings[] = array(
                            'item' => 'scorm',
                            'itemid' => $scorm->id,
                            'warningcode' => $warningkey,
                            'message' => get_string($warningkey, 'scorm', $warningdata)
                        );
                    }
                } else {
                    $module['packagesize'] = 0;
                    // SCORM size.
                    if ($scorm->scormtype === SCORM_TYPE_LOCAL or $scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
                        if ($packagefile = $fs->get_file($context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)) {
                            $module['packagesize'] = $packagefile->get_filesize();
                            // Download URL.
                            $module['packageurl'] = moodle_url::make_webservice_pluginfile_url(
                                                    $context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)->out(false);
                        }
                    }

                    $module['protectpackagedownloads'] = get_config('scorm', 'protectpackagedownloads');

                    $viewablefields = array('version', 'maxgrade', 'grademethod', 'whatgrade', 'maxattempt', 'forcecompleted',
                                            'forcenewattempt', 'lastattemptlock', 'displayattemptstatus', 'displaycoursestructure',
                                            'sha1hash', 'md5hash', 'revision', 'launch', 'skipview', 'hidebrowse', 'hidetoc', 'nav',
                                            'navpositionleft', 'navpositiontop', 'auto', 'popup', 'width', 'height', 'timeopen',
                                            'timeclose', 'displayactivityname', 'scormtype', 'reference');

                    // Check additional permissions for returning optional private settings.
                    if (has_capability('moodle/course:manageactivities', $context)) {

                        $additionalfields = array('updatefreq', 'options', 'completionstatusrequired', 'completionscorerequired',
                                                  'completionstatusallscos', 'autocommit', 'timemodified', 'section', 'visible',
                                                  'groupmode', 'groupingid');
                        $viewablefields = array_merge($viewablefields, $additionalfields);

                    }

                    foreach ($viewablefields as $field) {
                        $module[$field] = $scorm->{$field};
                    }
                }

                $returnedscorms[] = $module;
            }
        }

        $result = array();
        $result['scorms'] = $returnedscorms;
        $result['warnings'] = $warnings;
        return $result;
    }
6867
public static function add_competency_to_course($courseid, $competencyid) {
        static::require_enabled();
        // Check the user have access to the course.
        self::validate_course($courseid);

        // First we do a permissions check.
        $context = context_course::instance($courseid);

        require_capability('moodle/competency:coursecompetencymanage', $context);

        $record = new stdClass();
        $record->courseid = $courseid;
        $record->competencyid = $competencyid;

        $competency = new competency($competencyid);

        // Can not add a competency that belong to a hidden framework.
        if ($competency->get_framework()->get('visible') == false) {
            throw new coding_exception('A competency belonging to hidden framework can not be linked to course');
        }

        $coursecompetency = new course_competency();
        $exists = $coursecompetency->get_records(array('courseid' => $courseid, 'competencyid' => $competencyid));
        if (!$exists) {
            $coursecompetency->from_record($record);
            if ($coursecompetency->create()) {
                return true;
            }
        }
        return false;
    }
1262154
public static function view_user_list($courseid) {
        global $CFG;
        require_once($CFG->dirroot . "/user/lib.php");
        require_once($CFG->dirroot . '/course/lib.php');

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

        $warnings = array();

        if (empty($params['courseid'])) {
            $params['courseid'] = SITEID;
        }

        $course = get_course($params['courseid']);

        if ($course->id == SITEID) {
            $context = context_system::instance();
        } else {
            $context = context_course::instance($course->id);
        }
        self::validate_context($context);

        course_require_view_participants($context);

        user_list_view($course, $context);

        $result = array();
        $result['status'] = true;
        $result['warnings'] = $warnings;
        return $result;
    }
287112
public static function data_for_course_competencies_page($courseid) {
        global $PAGE;
        $params = self::validate_parameters(self::data_for_course_competencies_page_parameters(), array(
            'courseid' => $courseid,
        ));
        self::validate_context(context_course::instance($params['courseid']));

        $renderable = new output\course_competencies_page($params['courseid']);
        $renderer = $PAGE->get_renderer('tool_lp');

        $data = $renderable->export_for_template($renderer);

        return $data;
    }
633477
public static function fetch_course_item($courseid) {
        if ($course_item = grade_item::fetch(array('courseid'=>$courseid, 'itemtype'=>'course'))) {
            return $course_item;
        }

        // first get category - it creates the associated grade item
        $course_category = grade_category::fetch_course_category($courseid);
        return $course_category->get_grade_item();
    }
1179468
protected static function fetch_concepts(array $glossaries) {
        global $DB;

        $glossarylist = implode(',', $glossaries);

        $sql = "SELECT id, glossaryid, concept, casesensitive, 0 AS category, fullmatch
                  FROM {glossary_entries}
                 WHERE glossaryid IN ($glossarylist) AND usedynalink = 1 AND approved = 1

                 UNION

                SELECT id, glossaryid, name AS concept, 1 AS casesensitive, 1 AS category, 1 AS fullmatch
                  FROM {glossary_categories}
                 WHERE glossaryid IN ($glossarylist) AND usedynalink = 1

                UNION

                SELECT ge.id, ge.glossaryid, ga.alias AS concept, ge.casesensitive, 0 AS category, ge.fullmatch
                  FROM {glossary_alias} ga
                  JOIN {glossary_entries} ge ON (ga.entryid = ge.id)
                 WHERE ge.glossaryid IN ($glossarylist) AND ge.usedynalink = 1 AND ge.approved = 1";

        $concepts = array();
        $rs = $DB->get_recordset_sql($sql);
        foreach ($rs as $concept) {
            $currentconcept = trim(strip_tags($concept->concept));

            // Concept must be HTML-escaped, so do the same as format_string to turn ampersands into &amp;.
            $currentconcept = replace_ampersands_not_followed_by_entity($currentconcept);

            if (empty($currentconcept)) {
                continue;
            }

            // Rule out any small integers, see MDL-1446.
            if (is_number($currentconcept) and $currentconcept < 1000) {
                continue;
            }

            $concept->concept = $currentconcept;

            $concepts[$concept->glossaryid][] = $concept;
        }
        $rs->close();

        return $concepts;
    }
629480
public static function get_course_groupings($courseid) {
        global $CFG;
        require_once("$CFG->dirroot/group/lib.php");
        require_once("$CFG->libdir/filelib.php");

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

        // Now security checks.
        $context = context_course::instance($params['courseid']);

        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);
        }
        require_capability('moodle/course:managegroups', $context);

        $gs = groups_get_all_groupings($params['courseid']);

        $groupings = array();
        foreach ($gs as $grouping) {
            list($grouping->description, $grouping->descriptionformat) =
                external_format_text($grouping->description, $grouping->descriptionformat,
                        $context->id, 'grouping', 'description', $grouping->id);
            $groupings[] = (array)$grouping;
        }

        return $groupings;
    }
856288
public static function get_records_by_competencyid_in_course($competencyid, $courseid) {
        global $DB;

        $sql = 'SELECT cmc.*
                  FROM {' . self::TABLE . '} cmc
                  JOIN {course_modules} cm
                    ON cm.course = ?
                   AND cmc.cmid = cm.id
                 WHERE cmc.competencyid = ?
              ORDER BY cmc.sortorder ASC';
        $params = array($courseid, $competencyid);

        $results = $DB->get_recordset_sql($sql, $params);
        $instances = array();
        foreach ($results as $result) {
            $instances[$result->id] = new course_module_competency(0, $result);
        }
        $results->close();

        return $instances;
    }
1086453
protected function get_all_concepts() {
        global $USER;

        if ($this->cache === null) {
            $this->cache = cache::make_from_params(cache_store::MODE_REQUEST, 'filter', 'glossary');
        }

        // Try to get current course.
        $coursectx = $this->context->get_course_context(false);
        if (!$coursectx) {
            // Only global glossaries will be linked.
            $courseid = 0;
        } else {
            $courseid = $coursectx->instanceid;
        }

        $cached = $this->cache->get('concepts');
        if ($cached !== false && ($cached->cachecourseid != $courseid || $cached->cacheuserid != $USER->id)) {
            // Invalidate the page cache.
            $cached = false;
        }

        if ($cached !== false && is_array($cached->cacheconceptlist)) {
            return $cached->cacheconceptlist;
        }

        list($glossaries, $allconcepts) = \mod_glossary\local\concept_cache::get_concepts($courseid);

        if (!$allconcepts) {
            $tocache = new stdClass();
            $tocache->cacheuserid = $USER->id;
            $tocache->cachecourseid = $courseid;
            $tocache->cacheconceptlist = [];
            $this->cache->set('concepts', $tocache);
            return [];
        }

        $conceptlist = array();

        foreach ($allconcepts as $concepts) {
            foreach ($concepts as $concept) {
                $conceptlist[] = new filterobject($concept->concept, null, null,
                        $concept->casesensitive, $concept->fullmatch, null,
                        [$this, 'filterobject_prepare_replacement_callback'], [$concept, $glossaries]);
            }
        }

        // We sort longest first, so that when we replace the terms,
        // the longest ones are replaced first. This does the right thing
        // when you have two terms like 'Moodle' and 'Moodle 3.5'. You want the longest match.
        usort($conceptlist, [$this, 'sort_entries_by_length']);

        $conceptlist = filter_prepare_phrases_for_filtering($conceptlist);

        $tocache = new stdClass();
        $tocache->cacheuserid = $USER->id;
        $tocache->cachecourseid = $courseid;
        $tocache->cacheconceptlist = $conceptlist;
        $this->cache->set('concepts', $tocache);

        return $conceptlist;
    }
190312
public static function get_sections_from_courseid($courseid) {
        global $DB;

        // Get all sections belonging to requested course
        $sectionsarr = array();
        $sections = $DB->get_records('course_sections', array('course' => $courseid), 'section');
        foreach ($sections as $section) {
            $sectionsarr[] = $section->id;
        }
        return $sectionsarr;
    }
678390
public static function get_workshops_by_courses($courseids = array()) {
        global $PAGE;

        $warnings = array();
        $returnedworkshops = array();

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

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

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

            list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);
            $output = $PAGE->get_renderer('core');

            // Get the workshops in this course, this function checks users visibility permissions.
            // We can avoid then additional validate_context calls.
            $workshops = get_all_instances_in_courses("workshop", $courses);
            foreach ($workshops as $workshop) {

                $context = context_module::instance($workshop->coursemodule);
                // Remove fields that are not from the workshop (added by get_all_instances_in_courses).
                unset($workshop->coursemodule, $workshop->context, $workshop->visible, $workshop->section, $workshop->groupmode,
                        $workshop->groupingid);

                $exporter = new workshop_summary_exporter($workshop, array('context' => $context));
                $returnedworkshops[] = $exporter->export($output);
            }
        }

        $result = array(
            'workshops' => $returnedworkshops,
            'warnings' => $warnings
        );
        return $result;
    }
1320002
protected static function get_global_concepts() {
        global $DB;

        $cache = \cache::make('mod_glossary', 'concepts');
        $data = $cache->get(0);
        if (is_array($data)) {
            list($glossaries, $allconcepts) = $data;

        } else {
            // Find all global glossaries - no access control here.
            $sql = "SELECT g.id, g.name
                      FROM {glossary} g
                      JOIN {course_modules} cm ON (cm.instance = g.id)
                      JOIN {modules} m ON (m.name = 'glossary' AND m.id = cm.module)
                     WHERE g.usedynalink = 1 AND g.globalglossary = 1 AND cm.visible = 1 AND m.visible = 1
                  ORDER BY g.globalglossary, g.id";
            $glossaries = $DB->get_records_sql_menu($sql);
            if (!$glossaries) {
                $data = array(array(), array());
                $cache->set(0, $data);
                return $data;
            }
            foreach ($glossaries as $id => $name) {
                $name = str_replace(':', '-', $name);
                $glossaries[$id] = replace_ampersands_not_followed_by_entity(strip_tags($name));
            }
            $allconcepts = self::fetch_concepts(array_keys($glossaries));
            foreach ($glossaries as $gid => $unused) {
                if (!isset($allconcepts[$gid])) {
                    unset($glossaries[$gid]);
                }
            }
            $cache->set(0, array($glossaries, $allconcepts));
        }

        // NOTE: no access control is here because it would be way too expensive to check access
        //       to all courses that contain the global glossaries.
        return array($glossaries, $allconcepts);
    }
27237
public function can_access_course($courseid) {
        $this->init_course_access();
        if (!array_key_exists($courseid, $this->courseaccess)) {
            $this->courseaccess[$courseid] = can_access_course($this->get_course($courseid)) ? 1 : 0;
            $this->cachechangedcourse = true;
        }
        return $this->courseaccess[$courseid];
    }
967740
public function get_samples($sampleids) {
        global $DB;

        list($sql, $params) = $DB->get_in_or_equal($sampleids, SQL_PARAMS_NAMED);
        $courses = $DB->get_records_select('course', "id $sql", $params);

        $courseids = array_keys($courses);
        $sampleids = array_combine($courseids, $courseids);

        $courses = array_map(function($course) {
            return array('course' => $course, 'context' => \context_course::instance($course->id));
        }, $courses);

        // No related data attached.
        return array($sampleids, $courses);
    }
338161
public static function get_quizzes_by_courses($courseids = array()) {
        global $USER;

        $warnings = array();
        $returnedquizzes = array();

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

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

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

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

            // Get the quizzes in this course, this function checks users visibility permissions.
            // We can avoid then additional validate_context calls.
            $quizzes = get_all_instances_in_courses("quiz", $courses);
            foreach ($quizzes as $quiz) {
                $context = context_module::instance($quiz->coursemodule);

                // Update quiz with override information.
                $quiz = quiz_update_effective_access($quiz, $USER->id);

                // Entry to return.
                $quizdetails = array();
                // First, we return information that any user can see in the web interface.
                $quizdetails['id'] = $quiz->id;
                $quizdetails['coursemodule']      = $quiz->coursemodule;
                $quizdetails['course']            = $quiz->course;
                $quizdetails['name']              = external_format_string($quiz->name, $context->id);

                if (has_capability('mod/quiz:view', $context)) {
                    // Format intro.
                    list($quizdetails['intro'], $quizdetails['introformat']) = external_format_text($quiz->intro,
                                                                    $quiz->introformat, $context->id, 'mod_quiz', 'intro', null);

                    $quizdetails['introfiles'] = external_util::get_area_files($context->id, 'mod_quiz', 'intro', false, false);
                    $viewablefields = array('timeopen', 'timeclose', 'grademethod', 'section', 'visible', 'groupmode',
                                            'groupingid', 'attempts', 'timelimit', 'grademethod', 'decimalpoints',
                                            'questiondecimalpoints', 'sumgrades', 'grade', 'preferredbehaviour');
                    // Some times this function returns just empty.
                    $hasfeedback = quiz_has_feedback($quiz);
                    $quizdetails['hasfeedback'] = (!empty($hasfeedback)) ? 1 : 0;

                    $timenow = time();
                    $quizobj = quiz::create($quiz->id, $USER->id);
                    $accessmanager = new quiz_access_manager($quizobj, $timenow, has_capability('mod/quiz:ignoretimelimits',
                                                                $context, null, false));

                    // Fields the user could see if have access to the quiz.
                    if (!$accessmanager->prevent_access()) {
                        $quizdetails['hasquestions'] = (int) $quizobj->has_questions();
                        $quizdetails['autosaveperiod'] = get_config('quiz', 'autosaveperiod');

                        $additionalfields = array('attemptonlast', 'reviewattempt', 'reviewcorrectness', 'reviewmarks',
                                                    'reviewspecificfeedback', 'reviewgeneralfeedback', 'reviewrightanswer',
                                                    'reviewoverallfeedback', 'questionsperpage', 'navmethod',
                                                    'browsersecurity', 'delay1', 'delay2', 'showuserpicture', 'showblocks',
                                                    'completionattemptsexhausted', 'completionpass', 'overduehandling',
                                                    'graceperiod', 'canredoquestions', 'allowofflineattempts');
                        $viewablefields = array_merge($viewablefields, $additionalfields);
                    }

                    // Fields only for managers.
                    if (has_capability('moodle/course:manageactivities', $context)) {
                        $additionalfields = array('shuffleanswers', 'timecreated', 'timemodified', 'password', 'subnet');
                        $viewablefields = array_merge($viewablefields, $additionalfields);
                    }

                    foreach ($viewablefields as $field) {
                        $quizdetails[$field] = $quiz->{$field};
                    }
                }
                $returnedquizzes[] = $quizdetails;
            }
        }
        $result = array();
        $result['quizzes'] = $returnedquizzes;
        $result['warnings'] = $warnings;
        return $result;
    }
316079
public static function list_course_competencies($courseorid) {
        static::require_enabled();
        $course = $courseorid;
        if (!is_object($courseorid)) {
            $course = get_course($courseorid);
        }

        // Check the user have access to the course.
        self::validate_course($course);
        $context = context_course::instance($course->id);

        $capabilities = array('moodle/competency:coursecompetencyview', 'moodle/competency:coursecompetencymanage');
        if (!has_any_capability($capabilities, $context)) {
            throw new required_capability_exception($context, 'moodle/competency:coursecompetencyview', 'nopermissions', '');
        }

        $result = array();

        // TODO We could improve the performance of this into one single query.
        $coursecompetencies = course_competency::list_course_competencies($course->id);
        $competencies = course_competency::list_competencies($course->id);

        // Build the return values.
        foreach ($coursecompetencies as $key => $coursecompetency) {
            $result[] = array(
                'competency' => $competencies[$coursecompetency->get('competencyid')],
                'coursecompetency' => $coursecompetency
            );
        }

        return $result;
    }