Log user competency viewed in plan event.

@param user_competency|int $usercompetencyorid The user competency object or user competency id
@param int $planid The plan ID
@return bool
542277
public static function user_competency_viewed_in_plan($usercompetencyorid, $planid) {
        static::require_enabled();
        $uc = $usercompetencyorid;
        if (!is_object($uc)) {
            $uc = new user_competency($uc);
        }

        if (!$uc || !$uc->can_read()) {
            throw new required_capability_exception($uc->get_context(), 'moodle/competency:usercompetencyview',
                'nopermissions', '');
        }
        $plan = new plan($planid);
        if ($plan->get('status') == plan::STATUS_COMPLETE) {
            throw new coding_exception('To log the user competency in completed plan use user_competency_plan_viewed method.');
        }

        \core\event\competency_user_competency_viewed_in_plan::create_from_user_competency_viewed_in_plan($uc, $planid)->trigger();
        return true;
    }
129454
public static function user_competency_plan_viewed($competencyid, $userid, $planid) {
        $params = self::validate_parameters(self::user_competency_viewed_in_plan_parameters(), array(
            'competencyid' => $competencyid,
            'userid' => $userid,
            'planid' => $planid
        ));
        $pl = api::get_plan_competency($params['planid'], $params['competencyid']);
        $result = api::user_competency_plan_viewed($pl->usercompetencyplan);

        return $result;
    }
1111410
public static function reorder_plan_competency($planid, $competencyidfrom, $competencyidto) {
        $params = self::validate_parameters(self::reorder_plan_competency_parameters(), array(
            'planid' => $planid,
            'competencyidfrom' => $competencyidfrom,
            'competencyidto' => $competencyidto,
        ));

        $plan = api::read_plan($params['planid']);
        self::validate_context($plan->get_context());

        return api::reorder_plan_competency($params['planid'], $params['competencyidfrom'], $params['competencyidto']);
    }
367114
public static function user_competency_viewed_in_plan($competencyid, $userid, $planid) {
        $params = self::validate_parameters(self::user_competency_viewed_in_plan_parameters(), array(
            'competencyid' => $competencyid,
            'userid' => $userid,
            'planid' => $planid
        ));
        $pl = api::get_plan_competency($params['planid'], $params['competencyid']);
        $result = api::user_competency_viewed_in_plan($pl->usercompetency, $params['planid']);

        return $result;
    }
458355
public static function can_read_user($userid) {
        $capability = 'moodle/competency:usercompetencyview';
        return has_capability($capability, context_user::instance($userid))
            || plan::can_read_user($userid);
    }
506410
public function is_participant($userid=null) {
        global $USER, $DB;

        if (is_null($userid)) {
            $userid = $USER->id;
        }

        list($sql, $params) = $this->get_participants_sql();

        if (empty($sql)) {
            return false;
        }

        $sql = "SELECT COUNT(*)
                  FROM {user} uxx
                  JOIN ({$sql}) pxx ON uxx.id = pxx.id
                 WHERE uxx.id = :uxxid";
        $params['uxxid'] = $userid;

        if ($DB->count_records_sql($sql, $params)) {
            return true;
        }

        return false;
    }
236152
public function findByUserAndCompetencyIds(User $user, array $competencyIds)
    {
        if (0 === count($competencyIds)) {
            return [];
        }

        return $this->createQueryBuilder('p')
            ->select('p', 'c')
            ->join('p.competency', 'c')
            ->where('p.user = :user')
            ->andWhere((new Expr())->in('p.competency', $competencyIds))
            ->setParameter(':user', $user)
            ->getQuery()
            ->getResult();
    }
1106118
protected static function export_user_data_competencies_related_to_me($userid, context_user $context) {
        global $DB;

        $path = [
            get_string('competencies', 'core_competency'),
            get_string('privacy:path:relatedtome', 'core_competency'),
            get_string('competencies', 'core_competency'),
        ];
        $competencies = [];
        $helper = new performance_helper();
        $cfields = competency::get_sql_fields('c', 'c_');
        $ucfields = user_competency::get_sql_fields('uc', 'uc_');
        $efields = evidence::get_sql_fields('e', 'e_');

        $initcompetency = function($record) use (&$competencies) {
            $competency = new competency(null, competency::extract_record($record, 'c_'));
            $competencies[$competency->get('id')] = array_merge(static::transform_competency_brief($competency), [
                'evidence' => []
            ]);
        };

        $initusercomp = function($competency, $record) use (&$competencies, $userid, $helper) {
            $competencyid = $competency->get('id');
            $uc = new user_competency(null, user_competency::extract_record($record, 'uc_'));
            $competencies[$competencyid]['uc_id'] = $uc->get('id');
            $competencies[$competencyid]['rating'] = static::transform_user_competency($userid, $uc, $competency, $helper);
        };

        // Look for evidence.
        $sql = "
            SELECT $efields, $ucfields, $cfields
              FROM {" . evidence::TABLE . "} e
              JOIN {" . user_competency::TABLE . "} uc
                ON uc.id = e.usercompetencyid
              JOIN {" . competency::TABLE . "} c
                ON c.id = uc.competencyid
             WHERE uc.userid = :targetuserid
               AND (e.usermodified = :userid1
                OR e.actionuserid = :userid2)
          ORDER BY c.id, e.id";
        $params = [
            'targetuserid' => $context->instanceid,
            'userid1' => $userid,
            'userid2' => $userid,
        ];
        $recordset = $DB->get_recordset_sql($sql, $params);
        foreach ($recordset as $record) {
            $competencyid = $record->c_id;
            $competency = new competency(null, competency::extract_record($record, 'c_'));

            if (!isset($competencies[$competencyid])) {
                $initcompetency($record);
            }

            if (!array_key_exists('rating', $competencies[$competencyid])) {
                $competencies[$competencyid]['rating'] = null;
                if ($record->uc_reviewerid == $userid || $record->uc_usermodified == $userid) {
                    $initusercomp($competency, $record);
                }
            }

            $evidence = new evidence(null, evidence::extract_record($record, 'e_'));
            $competencies[$competencyid]['evidence'][] = static::transform_evidence($userid, $evidence, $competency, $helper);
        }
        $recordset->close();

        // Look for user competency we modified and didn't catch.
        $insql = ' > 0';
        $inparams = [];
        if (!empty($competencies)) {
            list($insql, $inparams) = $DB->get_in_or_equal(array_keys($competencies), SQL_PARAMS_NAMED, 'param', false);
        }
        $sql = "
            SELECT $ucfields, $cfields
              FROM {" . user_competency::TABLE . "} uc
              JOIN {" . competency::TABLE . "} c
                ON c.id = uc.competencyid
         LEFT JOIN {comments} cmt
                ON cmt.contextid = :contextid
               AND cmt.commentarea = :ucarea
               AND cmt.component = :competency
               AND cmt.itemid = uc.id
             WHERE uc.userid = :targetuserid
               AND (uc.usermodified = :userid1
                OR uc.reviewerid = :userid2
                OR cmt.userid = :userid3)
               AND uc.competencyid $insql
          ORDER BY c.id, uc.id";
        $params = array_merge($inparams, [
            'targetuserid' => $context->instanceid,
            'userid1' => $userid,
            'userid2' => $userid,
            'userid3' => $userid,
            'contextid' => $context->id,
            'ucarea' => 'user_competency',
            'competency' => 'competency',
        ]);

        $recordset = $DB->get_recordset_sql($sql, $params);
        foreach ($recordset as $record) {
            $competency = new competency(null, competency::extract_record($record, 'c_'));
            if (!isset($competencies[$competency->get('id')])) {
                $initcompetency($record);
                $initusercomp($competency, $record);
            }
        }
        $recordset->close();

        // Export each competency on its own.
        foreach ($competencies as $competencyid => $competency) {
            $comppath = array_merge($path, ["{$competency['name']} ({$competencyid})"]);
            $ucid = isset($competency['uc_id']) ? $competency['uc_id'] : null;
            unset($competency['uc_id']);

            // Send to writer.
            writer::with_context($context)->export_data($comppath, (object) $competency);
            if ($ucid) {
                \core_comment\privacy\provider::export_comments($context, 'competency', 'user_competency', $ucid, $comppath, true);
            }
        }
    }
333810
public static function create_user_evidence_competency($userevidenceorid, $competencyid) {
        global $USER;
        static::require_enabled();

        $userevidence = $userevidenceorid;
        if (!is_object($userevidence)) {
            $userevidence = self::read_user_evidence($userevidence);
        }

        // Perform user evidence capability checks.
        if (!$userevidence->can_manage()) {
            $context = $userevidence->get_context();
            throw new required_capability_exception($context, 'moodle/competency:userevidencemanage', 'nopermissions', '');
        }

        // Perform competency capability checks.
        $competency = self::read_competency($competencyid);

        // Get (and create) the relation.
        $relation = user_evidence_competency::get_relation($userevidence->get('id'), $competency->get('id'));
        if (!$relation->get('id')) {
            $relation->create();

            $link = url::user_evidence($userevidence->get('id'));
            self::add_evidence(
                $userevidence->get('userid'),
                $competency,
                $userevidence->get_context(),
                evidence::ACTION_LOG,
                'evidence_evidenceofpriorlearninglinked',
                'core_competency',
                $userevidence->get('name'),
                false,
                $link->out(false),
                null,
                $USER->id
            );
        }

        return $relation;
    }
196418
public static function plan_start_review($planorid) {
        global $USER;
        static::require_enabled();
        $plan = $planorid;
        if (!is_object($plan)) {
            $plan = new plan($plan);
        }

        // We need to be able to view the plan at least.
        if (!$plan->can_read()) {
            throw new required_capability_exception($plan->get_context(), 'moodle/competency:planview', 'nopermissions', '');
        }

        if ($plan->is_based_on_template()) {
            throw new coding_exception('Template plans cannot be reviewed.');   // This should never happen.
        } else if ($plan->get('status') != plan::STATUS_WAITING_FOR_REVIEW) {
            throw new coding_exception('The plan review cannot be started at this stage.');
        } else if (!$plan->can_review()) {
            throw new required_capability_exception($plan->get_context(), 'moodle/competency:planmanage', 'nopermissions', '');
        }

        $plan->set('status', plan::STATUS_IN_REVIEW);
        $plan->set('reviewerid', $USER->id);
        $result = $plan->update();

        // Trigger review started event.
        \core\event\competency_plan_review_started::create_from_plan($plan)->trigger();

        return $result;
    }
120635
protected static function export_user_data_in_course_contexts_rated_by_me($userid, $courseids, $path,
            performance_helper $helper) {
        global $DB;

        // Fetch all the records of competency proficiency in the course.
        $ffields = competency_framework::get_sql_fields('f', 'f_');
        $compfields = competency::get_sql_fields('c', 'c_');
        $uccfields = user_competency_course::get_sql_fields('ucc', 'ucc_');
        $ctxfields = context_helper::get_preload_record_columns_sql('ctx');
        list($insql, $inparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
        $sql = "
            SELECT $ffields, $compfields, $uccfields, $ctxfields
              FROM {" . user_competency_course::TABLE . "} ucc
              JOIN {" . competency::TABLE . "} c
                ON c.id = ucc.competencyid
              JOIN {" . competency_framework::TABLE . "} f
                ON f.id = c.competencyframeworkid
              JOIN {context} ctx
                ON ctx.id = f.contextid
             WHERE ucc.usermodified = :userid
               AND ucc.courseid $insql
          ORDER BY ucc.courseid, ucc.id";
        $params = array_merge($inparams, ['userid' => $userid]);

        // Export the data.
        static::recordset_loop_and_export($DB->get_recordset_sql($sql, $params), 'ucc_courseid', [],
            function($carry, $record) use ($helper) {
                context_helper::preload_from_record($record);

                $framework = new competency_framework(null, competency_framework::extract_record($record, 'f_'));
                $competency = new competency(null, competency::extract_record($record, 'c_'));
                $ucc = new user_competency_course(null, user_competency_course::extract_record($record, 'ucc_'));
                $helper->ingest_framework($framework);

                $carry[] = array_merge(static::transform_competency_brief($competency), [
                    'rating' => [
                        'userid' => transform::user($ucc->get('userid')),
                        'rating' => static::transform_competency_grade($competency, $ucc->get('grade'), $helper),
                        'proficient' => static::transform_proficiency($ucc->get('proficiency')),
                        'timemodified' => transform::datetime($ucc->get('timemodified')),
                    ]
                ]);
                return $carry;

            }, function($courseid, $data) use ($path) {
                $context = context_course::instance($courseid);
                writer::with_context($context)->export_related_data($path, 'rated_by_me', (object) [
                    'ratings' => $data
                ]);
            }
        );
    }
1132067
public static function data_for_user_competency_summary_in_course($userid, $competencyid, $courseid) {
        global $PAGE;
        $params = self::validate_parameters(self::data_for_user_competency_summary_in_course_parameters(), array(
            'userid' => $userid,
            'competencyid' => $competencyid,
            'courseid' => $courseid
        ));
        $context = context_user::instance($params['userid']);
        self::validate_context($context);
        $output = $PAGE->get_renderer('tool_lp');

        $renderable = new user_competency_summary_in_course($params['userid'], $params['competencyid'], $params['courseid']);
        return $renderable->export_for_template($output);
    }
398925
public static function user_competency_cancel_review_request($userid, $competencyid) {
        $params = self::validate_parameters(self::user_competency_cancel_review_request_parameters(), array(
            'userid' => $userid,
            'competencyid' => $competencyid
        ));

        $context = context_user::instance($params['userid']);
        self::validate_context($context);

        return api::user_competency_cancel_review_request($userid, $competencyid);
    }
672944
public static function reopen_plan($planorid) {
        global $DB;
        static::require_enabled();

        $plan = $planorid;
        if (!is_object($planorid)) {
            $plan = new plan($planorid);
        }

        // Validate that the plan as it is can be managed.
        if (!$plan->can_manage()) {
            $context = context_user::instance($plan->get('userid'));
            throw new required_capability_exception($context, 'moodle/competency:planmanage', 'nopermissions', '');
        }

        $beforestatus = $plan->get('status');
        $plan->set('status', plan::STATUS_ACTIVE);

        // Validate if status can be changed.
        if (!$plan->can_manage()) {
            $context = context_user::instance($plan->get('userid'));
            throw new required_capability_exception($context, 'moodle/competency:planmanage', 'nopermissions', '');
        }

        // Wrap the updates in a DB transaction.
        $transaction = $DB->start_delegated_transaction();

        // Delete archived user competencies if the status of the plan is changed from complete to another status.
        $mustremovearchivedcompetencies = ($beforestatus == plan::STATUS_COMPLETE && $plan->get('status') != plan::STATUS_COMPLETE);
        if ($mustremovearchivedcompetencies) {
            self::remove_archived_user_competencies_in_plan($plan);
        }

        // If duedate less than or equal to duedate_threshold unset it.
        if ($plan->get('duedate') <= time() + plan::DUEDATE_THRESHOLD) {
            $plan->set('duedate', 0);
        }

        $success = $plan->update();

        if (!$success) {
            $transaction->rollback(new moodle_exception('The plan could not be updated.'));
            return $success;
        }

        $transaction->allow_commit();

        // Trigger reopened event.
        \core\event\competency_plan_reopened::create_from_plan($plan)->trigger();

        return $success;
    }
692380
public static function user_competency_viewed_in_course($competencyid, $userid, $courseid) {
        $params = self::validate_parameters(self::user_competency_viewed_in_course_parameters(), array(
            'competencyid' => $competencyid,
            'userid' => $userid,
            'courseid' => $courseid
        ));
        $ucc = api::get_user_competency_in_course($params['courseid'], $params['userid'], $params['competencyid']);
        $result = api::user_competency_viewed_in_course($ucc);

        return $result;
    }
43119
public function isRated(RateableContract $rateable, $userId): bool
    {
        $userId = $this->getRaterUserId($userId);

        return $rateable->ratings()->where([
            'user_id' => $userId,
        ])->exists();
    }
144522
public static function get_user_competencies_by_userevidenceid($userevidenceid) {
        global $DB;

        $sql = "SELECT uc.*
                  FROM {" . user_competency::TABLE . "} uc
                  JOIN {" . self::TABLE . "} uec
                    ON uc.competencyid = uec.competencyid
                  JOIN {" . user_evidence::TABLE . "} ue
                    ON uec.userevidenceid = ue.id
                   AND uc.userid = ue.userid
                   AND ue.id = ?
              ORDER BY uc.id ASC";

        $usercompetencies = array();
        $records = $DB->get_recordset_sql($sql, array($userevidenceid));
        foreach ($records as $record) {
            $usercompetencies[] = new user_competency(0, $record);
        }
        $records->close();
        return $usercompetencies;
    }