public function get_criteria($criteriatype = null) {

        // Fill cache if empty
        if (!is_array($this->criteria)) {
            global $DB;

            $params = array(
                'course'    => $this->course->id
            );

            // Load criteria from database
            $records = (array)$DB->get_records('course_completion_criteria', $params);

            // Order records so activities are in the same order as they appear on the course view page.
            if ($records) {
                $activitiesorder = array_keys(get_fast_modinfo($this->course)->get_cms());
                usort($records, function ($a, $b) use ($activitiesorder) {
                    $aidx = ($a->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) ?
                        array_search($a->moduleinstance, $activitiesorder) : false;
                    $bidx = ($b->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) ?
                        array_search($b->moduleinstance, $activitiesorder) : false;
                    if ($aidx === false || $bidx === false || $aidx == $bidx) {
                        return 0;
                    }
                    return ($aidx < $bidx) ? -1 : 1;
                });
            }

            // Build array of criteria objects
            $this->criteria = array();
            foreach ($records as $record) {
                $this->criteria[$record->id] = completion_criteria::factory((array)$record);
            }
        }

        // If after all criteria
        if ($criteriatype === null) {
            return $this->criteria;
        }

        // If we are only after a specific criteria type
        $criteria = array();
        foreach ($this->criteria as $criterion) {

            if ($criterion->criteriatype != $criteriatype) {
                continue;
            }

            $criteria[$criterion->id] = $criterion;
        }

        return $criteria;
    }