Set a grade item.

@param object $gradeitem Grade Item record
@param object $score Result object
@param int $userid User ID

@throws \Exception
494487
public static function save_score($gradeitem, $score, $userid) {
        global $DB, $CFG;
        $source = 'mod' . self::SERVICE_NAME;
        if ($DB->get_record('user', array('id' => $userid)) === false) {
            throw new \Exception(null, 400);
        }
        require_once($CFG->libdir . '/gradelib.php');
        $finalgrade = null;
        $timemodified = null;
        if (isset($score->scoreGiven)) {
            $finalgrade = grade_floatval($score->scoreGiven);
            $max = 1;
            if (isset($score->scoreMaximum)) {
                $max = $score->scoreMaximum;
            }
            if (!is_null($max) && grade_floats_different($max, $gradeitem->grademax) && grade_floats_different($max, 0.0)) {
                // Rescale to match the grade item maximum.
                $finalgrade = grade_floatval($finalgrade * $gradeitem->grademax / $max);
            }
            if (isset($score->timestamp)) {
                $timemodified = strtotime($score->timestamp);
            } else {
                $timemodified = time();
            }
        }
        $feedbackformat = FORMAT_MOODLE;
        $feedback = null;
        if (isset($score->comment) && !empty($score->comment)) {
            $feedback = $score->comment;
            $feedbackformat = FORMAT_PLAIN;
        }

        if (!$grade = \grade_grade::fetch(array('itemid' => $gradeitem->id, 'userid' => $userid))) {
            $grade = new \grade_grade();
            $grade->userid = $userid;
            $grade->itemid = $gradeitem->id;
        }
        $grade->rawgrademax = $score->scoreMaximum;
        $grade->timemodified = $timemodified;
        $grade->feedbackformat = $feedbackformat;
        $grade->feedback = $feedback;
        if ($gradeitem->is_manual_item()) {
            $grade->finalgrade = $finalgrade;
            if (empty($grade->id)) {
                $result = (bool)$grade->insert($source);
            } else {
                $result = $grade->update($source);
            }
        } else {
            $grade->rawgrade = $finalgrade;
            $status = \grade_update($source, $gradeitem->courseid,
                         $gradeitem->itemtype, $gradeitem->itemmodule,
                         $gradeitem->iteminstance, $gradeitem->itemnumber,
                         $grade);

            $result = ($status == GRADE_UPDATE_OK);
        }
        if (!$result) {
            debugging("failed to save score for item ".$gradeitem->id." and user ".$grade->userid);
            throw new \Exception(null, 500);
        }

    }
1204881
public function isAssigned($itemName,$userId)
	{
		return $this->db->createCommand()
			->select('itemname')
			->from($this->assignmentTable)
			->where('itemname=:itemname AND userid=:userid', array(
				':itemname'=>$itemName,
				':userid'=>$userId))
			->queryScalar() !== false;
	}
1196344
public function revoke($itemName,$userId)
	{
		return $this->db->createCommand()
			->delete($this->assignmentTable, 'itemname=:itemname AND userid=:userid', array(
				':itemname'=>$itemName,
				':userid'=>$userId
			)) > 0;
	}
300618
public static function can_grade_user_in_course($userid, $courseid) {
        $ratecap = 'moodle/competency:competencygrade';
        return has_capability($ratecap, context_course::instance($courseid))
            || static::can_grade_user($userid);
    }
605593
public function set($value) {
        $finalgrade = false;
        $trimmed = trim($value);
        if (empty($trimmed)) {
            $feedback = null;
        } else {
            $feedback = $value;
        }

        $this->grade->grade_item->update_final_grade(
            $this->grade->userid, $finalgrade, 'singleview',
            $feedback, FORMAT_MOODLE
        );
    }
1246108
public function apply_limit_rules(&$grade_values, $items) {
        $extraused = $this->is_extracredit_used();

        if (!empty($this->droplow)) {
            asort($grade_values, SORT_NUMERIC);
            $dropped = 0;

            // If we have fewer grade items available to drop than $this->droplow, use this flag to escape the loop
            // May occur because of "extra credit" or if droplow is higher than the number of grade items
            $droppedsomething = true;

            while ($dropped < $this->droplow && $droppedsomething) {
                $droppedsomething = false;

                $grade_keys = array_keys($grade_values);
                $gradekeycount = count($grade_keys);

                if ($gradekeycount === 0) {
                    //We've dropped all grade items
                    break;
                }

                $originalindex = $founditemid = $foundmax = null;

                // Find the first remaining grade item that is available to be dropped
                foreach ($grade_keys as $gradekeyindex=>$gradekey) {
                    if (!$extraused || $items[$gradekey]->aggregationcoef <= 0) {
                        // Found a non-extra credit grade item that is eligible to be dropped
                        $originalindex = $gradekeyindex;
                        $founditemid = $grade_keys[$originalindex];
                        $foundmax = $items[$founditemid]->grademax;
                        break;
                    }
                }

                if (empty($founditemid)) {
                    // No grade items available to drop
                    break;
                }

                // Now iterate over the remaining grade items
                // We're looking for other grade items with the same grade value but a higher grademax
                $i = 1;
                while ($originalindex + $i < $gradekeycount) {

                    $possibleitemid = $grade_keys[$originalindex+$i];
                    $i++;

                    if ($grade_values[$founditemid] != $grade_values[$possibleitemid]) {
                        // The next grade item has a different grade value. Stop looking.
                        break;
                    }

                    if ($extraused && $items[$possibleitemid]->aggregationcoef > 0) {
                        // Don't drop extra credit grade items. Continue the search.
                        continue;
                    }

                    if ($foundmax < $items[$possibleitemid]->grademax) {
                        // Found a grade item with the same grade value and a higher grademax
                        $foundmax = $items[$possibleitemid]->grademax;
                        $founditemid = $possibleitemid;
                        // Continue searching to see if there is an even higher grademax
                    }
                }

                // Now drop whatever grade item we have found
                unset($grade_values[$founditemid]);
                $dropped++;
                $droppedsomething = true;
            }

        } else if (!empty($this->keephigh)) {
            arsort($grade_values, SORT_NUMERIC);
            $kept = 0;

            foreach ($grade_values as $itemid=>$value) {

                if ($extraused and $items[$itemid]->aggregationcoef > 0) {
                    // we keep all extra credits

                } else if ($kept < $this->keephigh) {
                    $kept++;

                } else {
                    unset($grade_values[$itemid]);
                }
            }
        }
    }
1358618
public static function user_competency_request_review($userid, $competencyid) {
        static::require_enabled();
        $uc = user_competency::get_record(array('userid' => $userid, 'competencyid' => $competencyid));
        if (!$uc) {
            $uc = user_competency::create_relation($userid, $competencyid);
            $uc->create();
        }

        if (!$uc->can_read()) {
            throw new required_capability_exception($uc->get_context(), 'moodle/competency:usercompetencyview',
                'nopermissions', '');
        } else if ($uc->get('status') != user_competency::STATUS_IDLE) {
            throw new coding_exception('The competency can not be sent for review at this stage.');
        } else if (!$uc->can_request_review()) {
            throw new required_capability_exception($uc->get_context(), 'moodle/competency:usercompetencyrequestreview',
                'nopermissions', '');
        }

        $uc->set('status', user_competency::STATUS_WAITING_FOR_REVIEW);
        $result = $uc->update();
        if ($result) {
            \core\event\competency_user_competency_review_requested::create_from_user_competency($uc)->trigger();
        }
        return $result;
    }
414172
public function notify_grade_modified($grade, $mailedoverride = false) {
        global $DB;

        $flags = $this->get_user_flags($grade->userid, true);
        if ($flags->mailed != 1 || $mailedoverride) {
            $flags->mailed = 0;
        }

        return $this->update_user_flags($flags);
    }
226379
public function load_grade_item() {
        if (empty($this->grade_item)) {
            $this->grade_item = $this->get_grade_item();
        }
        return $this->grade_item;
    }
68107
public function update_rating($rating) {
        global $DB;

        $time = time();

        $data = new stdClass;
        $data->rating       = $rating;
        $data->timemodified = $time;

        $item = new stdclass();
        $item->id = $this->itemid;
        $items = array($item);

        $ratingoptions = new stdClass;
        $ratingoptions->context = $this->context;
        $ratingoptions->component = $this->component;
        $ratingoptions->ratingarea = $this->ratingarea;
        $ratingoptions->items = $items;
        $ratingoptions->aggregate = RATING_AGGREGATE_AVERAGE; // We dont actually care what aggregation method is applied.
        $ratingoptions->scaleid = $this->scaleid;
        $ratingoptions->userid = $this->userid;

        $rm = new rating_manager();
        $items = $rm->get_ratings($ratingoptions);
        $firstitem = $items[0]->rating;

        if (empty($firstitem->id)) {
            // Insert a new rating.
            $data->contextid    = $this->context->id;
            $data->component    = $this->component;
            $data->ratingarea   = $this->ratingarea;
            $data->rating       = $rating;
            $data->scaleid      = $this->scaleid;
            $data->userid       = $this->userid;
            $data->itemid       = $this->itemid;
            $data->timecreated  = $time;
            $data->timemodified = $time;
            $DB->insert_record('rating', $data);
        } else {
            // Update the rating.
            $data->id           = $firstitem->id;
            $DB->update_record('rating', $data);
        }
    }
588925
public function getItemAccessControls(string $itemId, string $userId = ''):array
    {
        if (! empty($userId)) {
            return $this->get("AccessControls(principalid={$userId},itemid={$itemId})");
        } else {
            return $this->get("Items({$itemId})/AccessControls");
        }
    }
16553
public function setLevel($level)
    {
        if (!array_key_exists($level, self::LEVEL_PRIORITIES)) {
            throw new Exception(self::ERR_INVALID_LEVEL);
        }

        $lowestPriority = self::LEVEL_PRIORITIES[$level];
        $accepted = [];

        foreach (self::LEVEL_PRIORITIES as $level => $priority) {
            if ($priority > $lowestPriority) {
                continue;
            }

            $accepted[] = $level;
        }

        $this->acceptedLevels = $accepted;
    }
552691
public static function user_competency_stop_review($userid, $competencyid) {
        static::require_enabled();
        $context = context_user::instance($userid);
        $uc = user_competency::get_record(array('userid' => $userid, 'competencyid' => $competencyid));
        if (!$uc || !$uc->can_read()) {
            throw new required_capability_exception($context, 'moodle/competency:usercompetencyview', 'nopermissions', '');
        } else if ($uc->get('status') != user_competency::STATUS_IN_REVIEW) {
            throw new coding_exception('The competency review can not be stopped at this stage.');
        } else if (!$uc->can_review()) {
            throw new required_capability_exception($context, 'moodle/competency:usercompetencyreview', 'nopermissions', '');
        }

        $uc->set('status', user_competency::STATUS_IDLE);
        $result = $uc->update();
        if ($result) {
            \core\event\competency_user_competency_review_stopped::create_from_user_competency($uc)->trigger();
        }
        return $result;
    }
839567
public static function viewed($context, $courseid, $userid) {
        $event = \gradereport_overview\event\grade_report_viewed::create(
            array(
                'context' => $context,
                'courseid' => $courseid,
                'relateduserid' => $userid,
            )
        );
        $event->trigger();
    }
211239
public static function user_competency_start_review($userid, $competencyid) {
        $params = self::validate_parameters(self::user_competency_start_review_parameters(), array(
            'userid' => $userid,
            'competencyid' => $competencyid
        ));

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

        return api::user_competency_start_review($userid, $competencyid);
    }
1115201
public function updateItem(ItemInterface $item, $itemData, $locale, $userId)
    {
        return $this->itemManager->save($itemData, $locale, $userId, $item);
    }
407873
public static function grade_competency_in_course($courseid, $userid, $competencyid, $grade, $note = null) {
        global $USER, $PAGE, $DB;

        $params = self::validate_parameters(self::grade_competency_in_course_parameters(), array(
            'courseid' => $courseid,
            'userid' => $userid,
            'competencyid' => $competencyid,
            'grade' => $grade,
            'note' => $note
        ));

        $course = $DB->get_record('course', array('id' => $params['courseid']));
        $context = context_course::instance($course->id);
        self::validate_context($context);
        $output = $PAGE->get_renderer('core');

        $evidence = api::grade_competency_in_course(
                $params['courseid'],
                $params['userid'],
                $params['competencyid'],
                $params['grade'],
                $params['note']
        );
        $competency = api::read_competency($params['competencyid']);
        $scale = $competency->get_scale();
        $exporter = new evidence_exporter($evidence, array(
            'actionuser' => $USER,
            'scale' => $scale,
            'usercompetency' => null,
            'usercompetencyplan' => null,
            'context' => $evidence->get_context(),
        ));
        return $exporter->export($output);
    }