Create a learning plan from a template.

@param  mixed $templateorid The template object or ID.
@param  int $userid
@return false|\core_competency\plan Returns false when the plan already exists.
420914
public static function create_plan_from_template($templateorid, $userid) {
        static::require_enabled();
        $template = $templateorid;
        if (!is_object($template)) {
            $template = new template($template);
        }

        // The user must be able to view the template to use it as a base for a plan.
        if (!$template->can_read()) {
            throw new required_capability_exception($template->get_context(), 'moodle/competency:templateview',
                'nopermissions', '');
        }
        // Can not create plan from a hidden template.
        if ($template->get('visible') == false) {
            throw new coding_exception('A plan can not be created from a hidden template');
        }

        // Convert the template to a plan.
        $record = $template->to_record();
        $record->templateid = $record->id;
        $record->userid = $userid;
        $record->name = $record->shortname;
        $record->status = plan::STATUS_ACTIVE;

        unset($record->id);
        unset($record->timecreated);
        unset($record->timemodified);
        unset($record->usermodified);

        // Remove extra keys.
        $properties = plan::properties_definition();
        foreach ($record as $key => $value) {
            if (!array_key_exists($key, $properties)) {
                unset($record->$key);
            }
        }

        $plan = new plan(0, $record);
        if (!$plan->can_manage()) {
            throw new required_capability_exception($plan->get_context(), 'moodle/competency:planmanage',
                'nopermissions', '');
        }

        // We first apply the permission checks as we wouldn't want to leak information by returning early that
        // the plan already exists.
        if (plan::record_exists_select('templateid = :templateid AND userid = :userid', array(
                'templateid' => $template->get('id'), 'userid' => $userid))) {
            return false;
        }

        $plan->create();

        // Trigger created event.
        \core\event\competency_plan_created::create_from_plan($plan)->trigger();
        return $plan;
    }
372147
public static function add_competency_to_template($templateid, $competencyid) {
        static::require_enabled();
        // First we do a permissions check.
        $template = new template($templateid);
        if (!$template->can_manage()) {
            throw new required_capability_exception($template->get_context(), 'moodle/competency:templatemanage',
                'nopermissions', '');
        }

        $record = new stdClass();
        $record->templateid = $templateid;
        $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 added');
        }

        $exists = template_competency::get_records(array('templateid' => $templateid, 'competencyid' => $competencyid));
        if (!$exists) {
            $templatecompetency = new template_competency(0, $record);
            $templatecompetency->create();
            return true;
        }
        return false;
    }
423361
protected static function export_user_data_templates_in_context($userid, context $context) {
        global $DB;

        $tfields = template::get_sql_fields('t', 't_');
        $cfields = competency::get_sql_fields('c', 'c_');
        $tcfields = template_competency::get_sql_fields('tc', 'tc_');
        $tchfields = template_cohort::get_sql_fields('tch', 'tch_');

        $templates = [];
        $inittemplate = function($record) use (&$templates, $userid) {
            $template = new template(null, template::extract_record($record, 't_'));
            $templates[$template->get('id')] = array_merge(static::transform_template_brief($template), [
                'timemodified' => transform::datetime($template->get('timemodified')),
                'created_or_modified_by_you' => transform::yesno($template->get('usermodified') == $userid),
                'competencies' => [],
                'cohorts' => []
            ]);
        };

        // Find the template competencies.
        $sql = "
            SELECT $tfields, $cfields, $tcfields
              FROM {" . template_competency::TABLE . "} tc
              JOIN {" . template::TABLE . "} t
                ON t.id = tc.templateid
              JOIN {" . competency::TABLE . "} c
                ON c.id = tc.competencyid
             WHERE t.contextid = :contextid
               AND tc.usermodified = :userid
          ORDER BY t.id, tc.id";
        $params = ['userid' => $userid, 'contextid' => $context->id];
        $recordset = $DB->get_recordset_sql($sql, $params);
        foreach ($recordset as $record) {
            $templateid = $record->t_id;
            if (!isset($templates[$templateid])) {
                $inittemplate($record);
            }
            $tplcomp = new template_competency(null, template_competency::extract_record($record, 'tc_'));
            $competency = new competency(null, competency::extract_record($record, 'c_'));
            $templates[$templateid]['competencies'][] = array_merge(
                static::transform_competency_brief($competency),
                [
                    'timemodified' => transform::datetime($tplcomp->get('timemodified')),
                    'created_or_modified_by_you' => transform::yesno($tplcomp->get('usermodified') == $userid)
                ]
            );
        }
        $recordset->close();

        // Find the template cohorts.
        $sql = "
            SELECT $tfields, $tchfields, c.name AS cohortname
              FROM {" . template_cohort::TABLE . "} tch
              JOIN {" . template::TABLE . "} t
                ON t.id = tch.templateid
              JOIN {cohort} c
                ON c.id = tch.cohortid
             WHERE t.contextid = :contextid
               AND tch.usermodified = :userid
          ORDER BY t.id, tch.id";
        $params = ['userid' => $userid, 'contextid' => $context->id];
        $recordset = $DB->get_recordset_sql($sql, $params);
        foreach ($recordset as $record) {
            $templateid = $record->t_id;
            if (!isset($templates[$templateid])) {
                $inittemplate($record);
            }
            $tplcohort = new template_cohort(null, template_cohort::extract_record($record, 'tch_'));
            $templates[$templateid]['cohorts'][] = [
                'name' => $record->cohortname,
                'timemodified' => transform::datetime($tplcohort->get('timemodified')),
                'created_or_modified_by_you' => transform::yesno($tplcohort->get('usermodified') == $userid)
            ];
        }
        $recordset->close();

        // Find the modified templates which we haven't been found yet.
        $templateids = array_keys($templates);
        $insql = "IS NOT NULL";
        $inparams = [];
        if (!empty($templateids)) {
            list($insql, $inparams) = $DB->get_in_or_equal($templateids, SQL_PARAMS_NAMED, 'param', false);
        }
        $sql = "
            SELECT $tfields
              FROM {" . template::TABLE . "} t
             WHERE t.contextid = :contextid
               AND t.usermodified = :userid
               AND t.id $insql
          ORDER BY t.id";
        $params = array_merge($inparams, ['userid' => $userid, 'contextid' => $context->id]);
        $recordset = $DB->get_recordset_sql($sql, $params);
        foreach ($recordset as $record) {
            $inittemplate($record);
        }
        $recordset->close();

        // Export all the things!
        writer::with_context($context)->export_related_data([get_string('competencies', 'core_competency')],
            'templates', (object) ['templates' => array_values($templates)]);
    }
1092222
public static function template_viewed($templateorid) {
        static::require_enabled();
        $template = $templateorid;
        if (!is_object($template)) {
            $template = new template($template);
        }

        // First we do a permissions check.
        if (!$template->can_read()) {
            throw new required_capability_exception($template->get_context(), 'moodle/competency:templateview',
                'nopermissions', '');
        }

        // Trigger a template viewed event.
        \core\event\competency_template_viewed::create_from_template($template)->trigger();

        return true;
    }
597549
public static function list_competencies_in_template($templateorid) {
        static::require_enabled();
        // First we do a permissions check.
        $template = $templateorid;
        if (!is_object($template)) {
            $template = new template($template);
        }

        if (!$template->can_read()) {
            throw new required_capability_exception($template->get_context(), 'moodle/competency:templateview',
                'nopermissions', '');
        }

        // OK - all set.
        return template_competency::list_competencies($template->get('id'));
    }
427085
public static function can_create_data_deletion_request_for_children(int $userid, int $requesterid = null): bool {
        global $USER;
        $requesterid = $requesterid ?: $USER->id;
        return has_capability('tool/dataprivacy:makedatadeletionrequestsforchildren', \context_user::instance($userid),
            $requesterid);
    }
761442
public static function remove_competency_from_plan($planid, $competencyid) {
        static::require_enabled();
        $plan = new plan($planid);

        // First we do a permissions check.
        if (!$plan->can_manage()) {
            $context = context_user::instance($plan->get('userid'));
            throw new required_capability_exception($context, 'moodle/competency:planmanage', 'nopermissions', '');

        } else if ($plan->is_based_on_template()) {
            throw new coding_exception('A competency can not be removed from a learning plan based on a template');
        }

        if (!$plan->can_be_edited()) {
            throw new coding_exception('A competency can not be removed from a learning plan completed');
        }

        $link = plan_competency::get_record(array('planid' => $planid, 'competencyid' => $competencyid));
        if ($link) {
            return $link->delete();
        }
        return false;
    }
1305741
public static function get_by_user_and_competency($userid, $competencyid) {
        global $DB;

        $sql = 'SELECT p.*
                  FROM {' . self::TABLE . '} p
             LEFT JOIN {' . plan_competency::TABLE . '} pc
                    ON pc.planid = p.id
                   AND pc.competencyid = :competencyid1
             LEFT JOIN {' . user_competency_plan::TABLE . '} ucp
                    ON ucp.planid = p.id
                   AND ucp.competencyid = :competencyid2
             LEFT JOIN {' . template_competency::TABLE . '} tc
                    ON tc.templateid = p.templateid
                   AND tc.competencyid = :competencyid3
                 WHERE p.userid = :userid
                   AND (pc.id IS NOT NULL
                    OR ucp.id IS NOT NULL
                    OR tc.id IS NOT NULL)
              ORDER BY p.id ASC';

        $params = array(
            'competencyid1' => $competencyid,
            'competencyid2' => $competencyid,
            'competencyid3' => $competencyid,
            'userid' => $userid
        );

        $plans = array();
        $records = $DB->get_records_sql($sql, $params);
        foreach ($records as $record) {
            $plans[$record->id] = new plan(0, $record);
        }

        return $plans;
    }
821199
public static function create_user_evidence_competency($userevidenceid, $competencyid) {
        global $PAGE;
        $params = self::validate_parameters(self::create_user_evidence_competency_parameters(), array(
            'userevidenceid' => $userevidenceid,
            'competencyid' => $competencyid,
        ));

        $userevidence = api::read_user_evidence($params['userevidenceid']);
        self::validate_context($userevidence->get_context());

        $relation = api::create_user_evidence_competency($userevidence, $competencyid);
        $exporter = new user_evidence_competency_exporter($relation);
        return $exporter->export($PAGE->get_renderer('core'));
    }
976390
public static function instance($userid, $strictness = MUST_EXIST) {
        global $DB;

        if ($context = context::cache_get(CONTEXT_USER, $userid)) {
            return $context;
        }

        if (!$record = $DB->get_record('context', array('contextlevel' => CONTEXT_USER, 'instanceid' => $userid))) {
            if ($user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0), 'id', $strictness)) {
                $record = context::insert_context_record(CONTEXT_USER, $user->id, '/'.SYSCONTEXTID, 0);
            }
        }

        if ($record) {
            $context = new context_user($record);
            context::cache_add($context);
            return $context;
        }

        return false;
    }
874572
public function isUserInRoleById(int $userId): bool
    {
        if (isset($this->users[$userId])) {
            return true;
        }

        return false;
    }
790107
public static function reorder_template_competency($templateid, $competencyidfrom, $competencyidto) {
        $params = self::validate_parameters(self::reorder_template_competency_parameters(), array(
            'templateid' => $templateid,
            'competencyidfrom' => $competencyidfrom,
            'competencyidto' => $competencyidto,
        ));

        $template = api::read_template($params['templateid']);
        self::validate_context($template->get_context());

        return api::reorder_template_competency($params['templateid'], $params['competencyidfrom'], $params['competencyidto']);
    }
238886
public static function create_template_cohort($templateorid, $cohortorid) {
        global $DB;
        static::require_enabled();

        $template = $templateorid;
        if (!is_object($template)) {
            $template = new template($template);
        }
        require_capability('moodle/competency:templatemanage', $template->get_context());

        $cohort = $cohortorid;
        if (!is_object($cohort)) {
            $cohort = $DB->get_record('cohort', array('id' => $cohort), '*', MUST_EXIST);
        }

        // Replicate logic in cohort_can_view_cohort() because we can't use it directly as we don't have a course context.
        $cohortcontext = context::instance_by_id($cohort->contextid);
        if (!$cohort->visible && !has_capability('moodle/cohort:view', $cohortcontext)) {
            throw new required_capability_exception($cohortcontext, 'moodle/cohort:view', 'nopermissions', '');
        }

        $tplcohort = template_cohort::get_relation($template->get('id'), $cohort->id);
        if (!$tplcohort->get('id')) {
            $tplcohort->create();
        }

        return $tplcohort;
    }
1182769
public static function get_user_plan($workshopid, $userid = 0) {
        global $USER;

        $params = array(
            'workshopid' => $workshopid,
            'userid' => $userid,
        );
        $params = self::validate_parameters(self::get_user_plan_parameters(), $params);

        list($workshop, $course, $cm, $context) = self::validate_workshop($params['workshopid']);

        // Extra checks so only users with permissions can view other users plans.
        if (empty($params['userid']) || $params['userid'] == $USER->id) {
            $userid = $USER->id;
        } else {
            require_capability('moodle/course:manageactivities', $context);
            $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
            core_user::require_active_user($user);
            if (!$workshop->check_group_membership($user->id)) {
                throw new moodle_exception('notingroup');
            }
            $userid = $user->id;
        }

        // Get the user plan information ready for external functions.
        $userplan = new workshop_user_plan($workshop, $userid);
        $userplan = array('phases' => $userplan->phases, 'examples' => $userplan->get_examples());
        foreach ($userplan['phases'] as $phasecode => $phase) {
            $phase->code = $phasecode;
            $userplan['phases'][$phasecode] = (array) $phase;
            foreach ($userplan['phases'][$phasecode]['tasks'] as $taskcode => $task) {
                $task->code = $taskcode;
                if ($task->link instanceof moodle_url) {
                    $task->link = $task->link->out(false);
                }
                $userplan['phases'][$phasecode]['tasks'][$taskcode] = (array) $task;
            }
            foreach ($userplan['phases'][$phasecode]['actions'] as $actioncode => $action) {
                if ($action->url instanceof moodle_url) {
                    $action->url = $action->url->out(false);
                }
                $userplan['phases'][$phasecode]['actions'][$actioncode] = (array) $action;
            }
        }

        $result['userplan'] = $userplan;
        $result['warnings'] = array();
        return $result;
    }
201110
public static function is_user_gradable_in_course($courseid, $userid) {
        global $CFG;

        $gradableuser = false;
        $coursecontext = \context_course::instance($courseid);
        if (is_enrolled($coursecontext, $userid, '', false)) {
            $roles = get_user_roles($coursecontext, $userid);
            $gradebookroles = explode(',', $CFG->gradebookroles);
            foreach ($roles as $role) {
                foreach ($gradebookroles as $gradebookrole) {
                    if ($role->roleid = $gradebookrole) {
                        $gradableuser = true;
                    }
                }
            }
        }

        return $gradableuser;
    }
1027953
public static function add_contexts_for_userid(contextlist $contextlist, $userid) {
        $sql = "
            SELECT ctx.id
              FROM {context} ctx
              JOIN {log} l
                ON (l.cmid = 0 AND l.course = ctx.instanceid AND ctx.contextlevel = :courselevel)
                OR (l.cmid > 0 AND l.cmid = ctx.instanceid AND ctx.contextlevel = :modulelevel)
                OR (l.course <= 0 AND ctx.id = :syscontextid)
             WHERE l.userid = :userid";
        $params = [
            'courselevel' => CONTEXT_COURSE,
            'modulelevel' => CONTEXT_MODULE,
            'syscontextid' => SYSCONTEXTID,
            'userid' => $userid,
        ];
        $contextlist->add_from_sql($sql, $params);
    }
971106
public static function create_from_ids($userfromid, $usertoid, $notificationid, $courseid) {
        // We may be sending a notification from the 'noreply' address, which means we are not actually sending a
        // notification from a valid user. In this case, we will set the userid to 0.
        // Check if the userid is valid.
        if (!\core_user::is_real_user($userfromid)) {
            $userfromid = 0;
        }

        // If the courseid is null, then set it to the site id.
        if (is_null($courseid)) {
            $courseid = SITEID;
        }

        $event = self::create(
            [
                'objectid' => $notificationid,
                'userid' => $userfromid,
                'context' => \context_system::instance(),
                'relateduserid' => $usertoid,
                'other' => [
                    'courseid' => $courseid
                ]
            ]
        );

        return $event;
    }