}
}
+
+/**
+ * Core grades external functions
+ *
+ * @package core_grades
+ * @category external
+ * @copyright 2012 Andrew Davis
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since Moodle 2.7
+ */
+class core_grades_external extends external_api {
+ /**
+ * Returns description of method parameters
+ *
+ * @return external_function_parameters
+ * @since Moodle 2.7
+ */
+ public static function get_grades_parameters() {
+ return new external_function_parameters(
+ array(
+ 'courseid' => new external_value(PARAM_INT, 'id of course'),
+ 'component' => new external_value(
+ PARAM_COMPONENT, 'A component, for example mod_forum or mod_quiz', VALUE_DEFAULT, ''),
+ 'activityid' => new external_value(PARAM_INT, 'The activity ID', VALUE_DEFAULT, null),
+ 'userids' => new external_multiple_structure(
+ new external_value(PARAM_INT, 'user ID'),
+ 'An array of user IDs, leave empty to just retrieve grade item information', VALUE_DEFAULT, array()
+ )
+ )
+ );
+ }
+
+ /**
+ * Retrieve grade items and, optionally, student grades
+ *
+ * @param int $courseid Course id
+ * @param string $component Component name
+ * @param int $activityid Activity id
+ * @param array $userids Array of user ids
+ * @return array Array of grades
+ * @since Moodle 2.7
+ */
+ public static function get_grades($courseid, $component = null, $activityid = null, $userids = array()) {
+ global $CFG, $USER, $DB;
+ require_once("$CFG->libdir/gradelib.php");
+
+ $params = self::validate_parameters(self::get_grades_parameters(),
+ array('courseid' => $courseid, 'component' => $component, 'activityid' => $activityid, 'userids' => $userids));
+
+ $coursecontext = context_course::instance($params['courseid']);
+
+ try {
+ self::validate_context($coursecontext);
+ } catch (Exception $e) {
+ $exceptionparam = new stdClass();
+ $exceptionparam->message = $e->getMessage();
+ $exceptionparam->courseid = $params['courseid'];
+ throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
+ }
+
+ $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST);
+
+ $access = false;
+ if (has_capability('moodle/grade:viewall', $coursecontext)) {
+ // Can view all user's grades in this course.
+ $access = true;
+
+ } else if ($course->showgrades && count($params['userids']) == 1) {
+ // Course showgrades == students/parents can access grades.
+
+ if ($params['userids'][0] == $USER->id and has_capability('moodle/grade:view', $coursecontext)) {
+ // Student can view their own grades in this course.
+ $access = true;
+
+ } else if (has_capability('moodle/grade:viewall', context_user::instance($params['userids'][0]))) {
+ // User can view the grades of this user. Parent most probably.
+ $access = true;
+ }
+ }
+
+ if (!$access) {
+ throw new moodle_exception('nopermissiontoviewgrades', 'error');
+ }
+
+ $itemtype = null;
+ $itemmodule = null;
+ if (!empty($params['component'])) {
+ list($itemtype, $itemmodule) = normalize_component($params['component']);
+ }
+
+ $cm = null;
+ if (!empty($itemmodule) && !empty($activityid)) {
+ if (! $cm = get_coursemodule_from_id($itemmodule, $activityid)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+ }
+
+ $cminstanceid = null;
+ if (!empty($cm)) {
+ $cminstanceid = $cm->instance;
+ }
+ $grades = grade_get_grades($params['courseid'], $itemtype, $itemmodule, $cminstanceid, $params['userids']);
+
+ $acitivityinstances = null;
+ if (empty($cm)) {
+ // If we're dealing with multiple activites load all the module info.
+ $modinfo = get_fast_modinfo($params['courseid']);
+ $acitivityinstances = $modinfo->get_instances();
+ }
+
+ foreach ($grades->items as $gradeitem) {
+ if (!empty($cm)) {
+ // If they only requested one activity we will already have the cm.
+ $modulecm = $cm;
+ } else if (!empty($gradeitem->itemmodule)) {
+ $modulecm = $acitivityinstances[$gradeitem->itemmodule][$gradeitem->iteminstance];
+ } else {
+ // Course grade item.
+ continue;
+ }
+
+ // Make student feedback ready for output.
+ foreach ($gradeitem->grades as $studentgrade) {
+ if (!empty($studentgrade->feedback)) {
+ list($studentgrade->feedback, $categoryinfo->feedbackformat) =
+ external_format_text($studentgrade->feedback, $studentgrade->feedbackformat,
+ $modulecm->id, $params['component'], 'feedback', null);
+ }
+ }
+ }
+
+ // Convert from objects to arrays so all web service clients are supported.
+ // While we're doing that we also remove grades the current user can't see due to hiding.
+ $gradesarray = array();
+ $canviewhidden = has_capability('moodle/grade:viewhidden', context_course::instance($params['courseid']));
+
+ $gradesarray['items'] = array();
+ foreach ($grades->items as $gradeitem) {
+ // Switch the stdClass instance for a grade item instance so we can call is_hidden() and use the ID.
+ $gradeiteminstance = self::get_grade_item(
+ $course->id, $gradeitem->itemtype, $gradeitem->itemmodule, $gradeitem->iteminstance, 0);
+ if (!$canviewhidden && $gradeiteminstance->is_hidden()) {
+ continue;
+ }
+ $gradeitemarray = (array)$gradeitem;
+ $gradeitemarray['grades'] = array();
+
+ if (!empty($gradeitem->grades)) {
+ foreach ($gradeitem->grades as $studentid => $studentgrade) {
+ $gradegradeinstance = grade_grade::fetch(
+ array(
+ 'userid' => $studentid,
+ 'itemid' => $gradeiteminstance->id
+ )
+ );
+ if (!$canviewhidden && $gradegradeinstance->is_hidden()) {
+ continue;
+ }
+ $gradeitemarray['grades'][$studentid] = (array)$studentgrade;
+ // Add the student ID as some WS clients can't access the array key.
+ $gradeitemarray['grades'][$studentid]['userid'] = $studentid;
+ }
+ }
+
+ // If they requested grades for multiple activities load the cm object now.
+ $modulecm = $cm;
+ if (empty($modulecm) && !empty($gradeiteminstance->itemmodule)) {
+ $modulecm = $acitivityinstances[$gradeiteminstance->itemmodule][$gradeiteminstance->iteminstance];
+ }
+ if ($gradeiteminstance->itemtype == 'course') {
+ $gradesarray['items']['course'] = $gradeitemarray;
+ $gradesarray['items']['course']['activityid'] = 'course';
+ } else {
+ $gradesarray['items'][$modulecm->id] = $gradeitemarray;
+ // Add the activity ID as some WS clients can't access the array key.
+ $gradesarray['items'][$modulecm->id]['activityid'] = $modulecm->id;
+ }
+ }
+
+ $gradesarray['outcomes'] = array();
+ foreach ($grades->outcomes as $outcome) {
+ $modulecm = $cm;
+ if (empty($modulecm)) {
+ $modulecm = $acitivityinstances[$outcome->itemmodule][$outcome->iteminstance];
+ }
+ $gradesarray['outcomes'][$modulecm->id] = (array)$outcome;
+ $gradesarray['outcomes'][$modulecm->id]['activityid'] = $modulecm->id;
+
+ $gradesarray['outcomes'][$modulecm->id]['grades'] = array();
+ if (!empty($outcome->grades)) {
+ foreach ($outcome->grades as $studentid => $studentgrade) {
+ if (!$canviewhidden) {
+ // Need to load the grade_grade object to check visibility.
+ $gradeiteminstance = self::get_grade_item(
+ $course->id, $outcome->itemtype, $outcome->itemmodule, $outcome->iteminstance, $outcome->itemnumber);
+ $gradegradeinstance = grade_grade::fetch(
+ array(
+ 'userid' => $studentid,
+ 'itemid' => $gradeiteminstance->id
+ )
+ );
+ // The grade grade may be legitimately missing if the student has no grade.
+ if (!empty($gradegradeinstance ) && $gradegradeinstance->is_hidden()) {
+ continue;
+ }
+ }
+ $gradesarray['outcomes'][$modulecm->id]['grades'][$studentid] = (array)$studentgrade;
+
+ // Add the student ID into the grade structure as some WS clients can't access the key.
+ $gradesarray['outcomes'][$modulecm->id]['grades'][$studentid]['userid'] = $studentid;
+ }
+ }
+ }
+
+ return $gradesarray;
+ }
+
+ /**
+ * Get a grade item
+ * @param int $courseid Course id
+ * @param string $itemtype Item type
+ * @param string $itemmodule Item module
+ * @param int $iteminstance Item instance
+ * @param int $itemnumber Item number
+ * @return grade_item A grade_item instance
+ */
+ private static function get_grade_item($courseid, $itemtype, $itemmodule = null, $iteminstance = null, $itemnumber = null) {
+ $gradeiteminstance = null;
+ if ($itemtype == 'course') {
+ $gradeiteminstance = grade_item::fetch(array('courseid' => $courseid, 'itemtype' => $itemtype));
+ } else {
+ $gradeiteminstance = grade_item::fetch(
+ array('courseid' => $courseid, 'itemtype' => $itemtype,
+ 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'itemnumber' => $itemnumber));
+ }
+ return $gradeiteminstance;
+ }
+
+ /**
+ * Returns description of method result value
+ *
+ * @return external_description
+ * @since Moodle 2.7
+ */
+ public static function get_grades_returns() {
+ return new external_single_structure(
+ array(
+ 'items' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'activityid' => new external_value(
+ PARAM_ALPHANUM, 'The ID of the activity or "course" for the course grade item'),
+ 'itemnumber' => new external_value(PARAM_INT, 'Will be 0 unless the module has multiple grades'),
+ 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale or 0'),
+ 'name' => new external_value(PARAM_RAW, 'The module name'),
+ 'grademin' => new external_value(PARAM_FLOAT, 'Minimum grade'),
+ 'grademax' => new external_value(PARAM_FLOAT, 'Maximum grade'),
+ 'gradepass' => new external_value(PARAM_FLOAT, 'The passing grade threshold'),
+ 'locked' => new external_value(PARAM_BOOL, 'Is the grade item locked?'),
+ 'hidden' => new external_value(PARAM_BOOL, 'Is the grade item hidden?'),
+ 'grades' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'userid' => new external_value(
+ PARAM_INT, 'Student ID'),
+ 'grade' => new external_value(
+ PARAM_FLOAT, 'Student grade'),
+ 'locked' => new external_value(
+ PARAM_BOOL, 'Is the student\'s grade locked?'),
+ 'hidden' => new external_value(
+ PARAM_BOOL, 'Is the student\'s grade hidden?'),
+ 'overridden' => new external_value(
+ PARAM_BOOL, 'Is the student\'s grade overridden?'),
+ 'feedback' => new external_value(
+ PARAM_RAW, 'Feedback from the grader'),
+ 'feedbackformat' => new external_value(
+ PARAM_INT, 'The format of the feedback'),
+ 'usermodified' => new external_value(
+ PARAM_INT, 'The ID of the last user to modify this student grade'),
+ 'datesubmitted' => new external_value(
+ PARAM_INT, 'A timestamp indicating when the student submitted the activity'),
+ 'dategraded' => new external_value(
+ PARAM_INT, 'A timestamp indicating when the assignment was grades'),
+ 'str_grade' => new external_value(
+ PARAM_RAW, 'A string representation of the grade'),
+ 'str_long_grade' => new external_value(
+ PARAM_RAW, 'A nicely formatted string representation of the grade'),
+ 'str_feedback' => new external_value(
+ PARAM_TEXT, 'A string representation of the feedback from the grader'),
+ )
+ )
+ ),
+ )
+ )
+ ),
+ 'outcomes' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'activityid' => new external_value(
+ PARAM_ALPHANUM, 'The ID of the activity or "course" for the course grade item'),
+ 'itemnumber' => new external_value(PARAM_INT, 'Will be 0 unless the module has multiple grades'),
+ 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale or 0'),
+ 'name' => new external_value(PARAM_RAW, 'The module name'),
+ 'locked' => new external_value(PARAM_BOOL, 'Is the grade item locked?'),
+ 'hidden' => new external_value(PARAM_BOOL, 'Is the grade item hidden?'),
+ 'grades' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'userid' => new external_value(
+ PARAM_INT, 'Student ID'),
+ 'grade' => new external_value(
+ PARAM_FLOAT, 'Student grade'),
+ 'locked' => new external_value(
+ PARAM_BOOL, 'Is the student\'s grade locked?'),
+ 'hidden' => new external_value(
+ PARAM_BOOL, 'Is the student\'s grade hidden?'),
+ 'feedback' => new external_value(
+ PARAM_RAW, 'Feedback from the grader'),
+ 'feedbackformat' => new external_value(
+ PARAM_INT, 'The feedback format'),
+ 'usermodified' => new external_value(
+ PARAM_INT, 'The ID of the last user to modify this student grade'),
+ 'str_grade' => new external_value(
+ PARAM_RAW, 'A string representation of the grade'),
+ 'str_feedback' => new external_value(
+ PARAM_TEXT, 'A string representation of the feedback from the grader'),
+ )
+ )
+ ),
+ )
+ ), 'An array of outcomes associated with the grade items', VALUE_OPTIONAL
+ )
+ )
+ );
+
+ }
+
+ /**
+ * Returns description of method parameters
+ *
+ * @return external_function_parameters
+ * @since Moodle 2.7
+ */
+ public static function update_grades_parameters() {
+ return new external_function_parameters(
+ array(
+ 'source' => new external_value(PARAM_TEXT, 'The source of the grade update'),
+ 'courseid' => new external_value(PARAM_INT, 'id of course'),
+ 'component' => new external_value(PARAM_COMPONENT, 'A component, for example mod_forum or mod_quiz'),
+ 'activityid' => new external_value(PARAM_INT, 'The activity ID'),
+ 'itemnumber' => new external_value(
+ PARAM_INT, 'grade item ID number for modules that have multiple grades. Typically this is 0.'),
+ 'grades' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'studentid' => new external_value(PARAM_INT, 'Student ID'),
+ 'grade' => new external_value(PARAM_FLOAT, 'Student grade'),
+ 'str_feedback' => new external_value(
+ PARAM_TEXT, 'A string representation of the feedback from the grader', VALUE_OPTIONAL),
+ )
+ ), 'Any student grades to alter', VALUE_OPTIONAL),
+ 'itemdetails' => new external_single_structure(
+ array(
+ 'itemname' => new external_value(
+ PARAM_ALPHANUMEXT, 'The grade item name', VALUE_OPTIONAL),
+ 'idnumber' => new external_value(
+ PARAM_INT, 'Arbitrary ID provided by the module responsible for the grade item', VALUE_OPTIONAL),
+ 'gradetype' => new external_value(
+ PARAM_INT, 'The type of grade (0 = none, 1 = value, 2 = scale, 3 = text)', VALUE_OPTIONAL),
+ 'grademax' => new external_value(
+ PARAM_FLOAT, 'Maximum grade allowed', VALUE_OPTIONAL),
+ 'grademin' => new external_value(
+ PARAM_FLOAT, 'Minimum grade allowed', VALUE_OPTIONAL),
+ 'scaleid' => new external_value(
+ PARAM_INT, 'The ID of the custom scale being is used', VALUE_OPTIONAL),
+ 'multfactor' => new external_value(
+ PARAM_FLOAT, 'Multiply all grades by this number', VALUE_OPTIONAL),
+ 'plusfactor' => new external_value(
+ PARAM_FLOAT, 'Add this to all grades', VALUE_OPTIONAL),
+ 'deleted' => new external_value(
+ PARAM_BOOL, 'True if the grade item should be deleted', VALUE_OPTIONAL),
+ 'hidden' => new external_value(
+ PARAM_BOOL, 'True if the grade item is hidden', VALUE_OPTIONAL),
+ ), 'Any grade item settings to alter', VALUE_OPTIONAL
+ )
+ )
+ );
+ }
+
+ /**
+ * Update a grade item and, optionally, student grades
+ *
+ * @param string $source The source of the grade update
+ * @param int $courseid The course id
+ * @param string $component Component name
+ * @param int $activityid The activity id
+ * @param int $itemnumber The item number
+ * @param array $grades Array of grades
+ * @param array $itemdetails Array of item details
+ * @return int A status flag
+ * @since Moodle 2.7
+ */
+ public static function update_grades($source, $courseid, $component, $activityid,
+ $itemnumber, $grades = array(), $itemdetails = array()) {
+ global $CFG;
+
+ require_once("$CFG->libdir/gradelib.php");
+
+ $params = self::validate_parameters(
+ self::update_grades_parameters(),
+ array(
+ 'source' => $source,
+ 'courseid' => $courseid,
+ 'component' => $component,
+ 'activityid' => $activityid,
+ 'itemnumber' => $itemnumber,
+ 'grades' => $grades,
+ 'itemdetails' => $itemdetails
+ )
+ );
+
+ list($itemtype, $itemmodule) = normalize_component($params['component']);
+
+ if (! $cm = get_coursemodule_from_id($itemmodule, $activityid)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+ $iteminstance = $cm->instance;
+
+ $coursecontext = context_course::instance($params['courseid']);
+
+ try {
+ self::validate_context($coursecontext);
+ } catch (Exception $e) {
+ $exceptionparam = new stdClass();
+ $exceptionparam->message = $e->getMessage();
+ $exceptionparam->courseid = $params['courseid'];
+ throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
+ }
+
+ $hidinggrades = false;
+ $editinggradeitem = false;
+ $editinggrades = false;
+
+ $gradestructure = array();
+ foreach ($grades as $grade) {
+ $editinggrades = true;
+ $gradestructure[ $grade['studentid'] ] = array('userid' => $grade['studentid'], 'rawgrade' => $grade['grade']);
+ }
+ if (!empty($params['itemdetails'])) {
+ if (isset($params['itemdetails']['hidden'])) {
+ $hidinggrades = true;
+ } else {
+ $editinggradeitem = true;
+ }
+ }
+
+ if ($editinggradeitem && !has_capability('moodle/grade:manage', $coursecontext)) {
+ throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null,
+ 'moodle/grade:manage required to edit grade information');
+ }
+ if ($hidinggrades && !has_capability('moodle/grade:hide', $coursecontext) &&
+ !has_capability('moodle/grade:hide', $coursecontext)) {
+ throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null,
+ 'moodle/grade:hide required to hide grade items');
+ }
+ if ($editinggrades && !has_capability('moodle/grade:edit', $coursecontext)) {
+ throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null,
+ 'moodle/grade:edit required to edit grades');
+ }
+
+ return grade_update($params['source'], $params['courseid'], $itemtype,
+ $itemmodule, $iteminstance, $itemnumber, $gradestructure, $params['itemdetails']);
+ }
+
+ /**
+ * Returns description of method result value
+ *
+ * @return external_description
+ * @since Moodle 2.7
+ */
+ public static function update_grades_returns() {
+ return new external_single_structure(
+ array (
+ 'result' => new external_value(
+ PARAM_INT,
+ 'A value like ' . GRADE_UPDATE_OK . ' => OK, ' . GRADE_UPDATE_FAILED . ' => FAILED
+ as defined in lib/grade/constants.php')
+ )
+ );
+ }
+}
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
- * Unit tests for the grade API at /lib/grade/externallib.php
+ * Unit tests for the grade API at /grade/externallib.php
*
- * @package core_grade
+ * @package core_grades
* @category external
* @copyright 2012 Andrew Davis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @since Moodle 2.6
+ * @since Moodle 2.7
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
-require_once($CFG->libdir . '/grade/externallib.php');
+require_once($CFG->dirroot . '/grade/externallib.php');
-class core_grade_external_testcase extends externallib_advanced_testcase {
+/**
+ * Grades functions unit tests
+ *
+ * @package core_grades
+ * @category external
+ * @copyright 2012 Andrew Davis
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_grades_external_testcase extends externallib_advanced_testcase {
+ /**
+ * Load initial test information
+ *
+ * @param string $assignmentname Assignment name
+ * @param int $student1rawgrade Student 1 grade
+ * @param int $student2rawgrade Student 2 grade
+ * @return array Array of vars with test information
+ */
protected function load_test_data($assignmentname, $student1rawgrade, $student2rawgrade) {
global $DB;
$course = $this->getDataGenerator()->create_course();
$coursecontext = context_course::instance($course->id);
- $studentrole = $DB->get_record('role', array('shortname'=>'student'));
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
- $student1 = $this->getDataGenerator()->create_user();
+ $student1 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
- $student2 = $this->getDataGenerator()->create_user();
+ $student2 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
- $teacherrole = $DB->get_record('role', array('shortname'=>'editingteacher'));
+ $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
$teacher = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id);
assign_grade_item_update($assignment, $studentgrades);
// Insert a custom grade scale to be used by an outcome.
- $grade_scale = new grade_scale();
- $grade_scale->name = 'unittestscale3';
- $grade_scale->courseid = $course->id;
- $grade_scale->userid = 0;
- $grade_scale->scale = 'Distinction, Very Good, Good, Pass, Fail';
- $grade_scale->description = 'This scale is used to mark standard assignments.';
- $grade_scale->insert();
+ $gradescale = new grade_scale();
+ $gradescale->name = 'unittestscale3';
+ $gradescale->courseid = $course->id;
+ $gradescale->userid = 0;
+ $gradescale->scale = 'Distinction, Very Good, Good, Pass, Fail';
+ $gradescale->description = 'This scale is used to mark standard assignments.';
+ $gradescale->insert();
// Insert an outcome.
$data = new stdClass();
$data->courseid = $course->id;
$data->fullname = 'Team work';
$data->shortname = 'Team work';
- $data->scaleid = $grade_scale->id;
+ $data->scaleid = $gradescale->id;
$outcome = new grade_outcome($data, false);
$outcome->insert();
- $outcome_gradeitem = new grade_item();
- $outcome_gradeitem->itemname = $outcome->shortname;
- $outcome_gradeitem->itemtype = 'mod';
- $outcome_gradeitem->itemmodule = 'assign';
- $outcome_gradeitem->iteminstance = $assignment->id;
- $outcome_gradeitem->outcomeid = $outcome->id;
- $outcome_gradeitem->cmid = 0;
- $outcome_gradeitem->courseid = $course->id;
- $outcome_gradeitem->aggregationcoef = 0;
- $outcome_gradeitem->itemnumber = 1; // The activity's original grade item will be 0.
- $outcome_gradeitem->gradetype = GRADE_TYPE_SCALE;
- $outcome_gradeitem->scaleid = $outcome->scaleid;
- $outcome_gradeitem->insert();
-
- $assignment_gradeitem = grade_item::fetch(
+ $outcomegradeitem = new grade_item();
+ $outcomegradeitem->itemname = $outcome->shortname;
+ $outcomegradeitem->itemtype = 'mod';
+ $outcomegradeitem->itemmodule = 'assign';
+ $outcomegradeitem->iteminstance = $assignment->id;
+ $outcomegradeitem->outcomeid = $outcome->id;
+ $outcomegradeitem->cmid = 0;
+ $outcomegradeitem->courseid = $course->id;
+ $outcomegradeitem->aggregationcoef = 0;
+ $outcomegradeitem->itemnumber = 1; // The activity's original grade item will be 0.
+ $outcomegradeitem->gradetype = GRADE_TYPE_SCALE;
+ $outcomegradeitem->scaleid = $outcome->scaleid;
+ $outcomegradeitem->insert();
+
+ $assignmentgradeitem = grade_item::fetch(
array(
'itemtype' => 'mod',
'itemmodule' => 'assign',
'courseid' => $course->id
)
);
- $outcome_gradeitem->set_parent($assignment_gradeitem->categoryid);
- $outcome_gradeitem->move_after_sortorder($assignment_gradeitem->sortorder);
+ $outcomegradeitem->set_parent($assignmentgradeitem->categoryid);
+ $outcomegradeitem->move_after_sortorder($assignmentgradeitem->sortorder);
return array($course, $assignment, $student1, $student2, $teacher, $parent);
}
$assignmentname = 'The assignment';
$student1rawgrade = 10;
$student2rawgrade = 20;
- list($course, $assignment, $student1, $student2, $teacher, $parent) = $this->load_test_data($assignmentname, $student1rawgrade, $student2rawgrade);
- $assigment_cm = get_coursemodule_from_id('assign', $assignment->id, 0, false, MUST_EXIST);
+ list($course, $assignment, $student1, $student2, $teacher, $parent) =
+ $this->load_test_data($assignmentname, $student1rawgrade, $student2rawgrade);
+ $assigmentcm = get_coursemodule_from_id('assign', $assignment->id, 0, false, MUST_EXIST);
// Student requesting their own grade for the assignment.
$this->setUser($student1);
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student1->id)
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
- $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigment_cm->id, $student1->id));
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
+ $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id));
// Student requesting all of their grades in a course.
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
null,
null,
array($student1->id)
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
$this->assertTrue(count($grades['items']) == 2);
- $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigment_cm->id, $student1->id));
+ $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id));
$this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, 'course', $student1->id));
- $outcome = $this->get_outcome($grades, $assigment_cm->id);
+ $outcome = $this->get_outcome($grades, $assigmentcm->id);
$this->assertEquals($outcome['name'], 'Team work');
- $this->assertEquals(0, $this->get_outcome_student_grade($grades, $assigment_cm->id, $student1->id));
+ $this->assertEquals(0, $this->get_outcome_student_grade($grades, $assigmentcm->id, $student1->id));
// Student requesting another student's grade for the assignment (should fail).
try {
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student2->id)
);
$this->fail('moodle_exception expected');
// Parent requesting their child's grade for the assignment.
$this->setUser($parent);
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student1->id)
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
- $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigment_cm->id, $student1->id));
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
+ $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id));
// Parent requesting another student's grade for the assignment(should fail).
try {
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student2->id)
);
$this->fail('moodle_exception expected');
// Student requesting all other student grades for the assignment (should fail).
try {
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student1->id, $student2->id)
);
$this->fail('moodle_exception expected');
// Student requesting only grade item information (should fail).
try {
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array()
);
$this->fail('moodle_exception expected');
// Teacher requesting student grades for a course.
$this->setUser($teacher);
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student1->id, $student2->id)
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
- $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigment_cm->id, $student1->id));
- $this->assertEquals($student2rawgrade, $this->get_activity_student_grade($grades, $assigment_cm->id, $student2->id));
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
+ $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id));
+ $this->assertEquals($student2rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student2->id));
// Teacher requesting grade item information.
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id
+ $assigmentcm->id
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
- $activity = $this->get_activity($grades, $assigment_cm->id);
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
+ $activity = $this->get_activity($grades, $assigmentcm->id);
$this->assertEquals($activity['name'], $assignmentname);
$this->assertEquals(count($activity['grades']), 0);
// Teacher requesting all grade items in a course.
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
$this->assertTrue(count($grades['items']) == 2);
- $activity = $this->get_activity($grades, $assigment_cm->id);
+ $activity = $this->get_activity($grades, $assigmentcm->id);
$this->assertEquals($activity['name'], $assignmentname);
$this->assertEquals(count($activity['grades']), 0);
- $outcome = $this->get_outcome($grades, $assigment_cm->id);
+ $outcome = $this->get_outcome($grades, $assigmentcm->id);
$this->assertEquals($outcome['name'], 'Team work');
- // Hide a grade item then have student request it
- $result = core_grade_external::update_grades(
+ // Hide a grade item then have student request it.
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array(),
array('hidden' => 1)
// Student should now not be able to see it.
$this->setUser($student1);
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student1->id)
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
- $this->assertEquals(null, $this->get_activity($grades, $assigment_cm->id));
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
+ $this->assertEquals(null, $this->get_activity($grades, $assigmentcm->id));
// Teacher should still be able to see the hidden grades.
$this->setUser($teacher);
- $grades = core_grade_external::get_grades(
+ $grades = core_grades_external::get_grades(
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
array($student1->id)
);
- $grades = external_api::clean_returnvalue(core_grade_external::get_grades_returns(), $grades);
- $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigment_cm->id, $student1->id));
+ $grades = external_api::clean_returnvalue(core_grades_external::get_grades_returns(), $grades);
+ $this->assertEquals($student1rawgrade, $this->get_activity_student_grade($grades, $assigmentcm->id, $student1->id));
}
+ /**
+ * Get an activity
+ *
+ * @param array $grades Array of grades
+ * @param int $cmid Activity course module id
+ * @return strdClass Activity object
+ */
private function get_activity($grades, $cmid) {
foreach ($grades['items'] as $item) {
if ($item['activityid'] == $cmid) {
return null;
}
+ /**
+ * Get a grade for an activity
+ *
+ * @param array $grades Array of grades
+ * @param int $cmid Activity course module id
+ * @param int $studentid Student it
+ * @return stdClass Activity Object
+ */
private function get_activity_student_grade($grades, $cmid, $studentid) {
$item = $this->get_activity($grades, $cmid);
foreach ($item['grades'] as $grade) {
}
return null;
}
-
+
+ /**
+ * Get an ouctome
+ *
+ * @param array $grades Array of grades
+ * @param int $cmid Activity course module id
+ * @return stdClass Outcome object
+ */
private function get_outcome($grades, $cmid) {
- foreach($grades['outcomes'] as $outcome) {
+ foreach ($grades['outcomes'] as $outcome) {
if ($outcome['activityid'] == $cmid) {
return $outcome;
}
}
return null;
}
-
+
+ /**
+ * Get a grade from an outcome
+ *
+ * @param array $grades Array of grades
+ * @param int $cmid Activity course module id
+ * @param int $studentid Student id
+ * @return stdClass Outcome object
+ */
private function get_outcome_student_grade($grades, $cmid, $studentid) {
$outcome = $this->get_outcome($grades, $cmid);
- foreach ($outcome['grades'] as $grade) {
+ foreach ($outcome['grades'] as $grade) {
if ($grade['userid'] == $studentid) {
return $grade['grade'];
}
}
/**
- * Test get_grades()
+ * Test update_grades()
*/
public function test_update_grades() {
global $DB;
$assignmentname = 'The assignment';
$student1rawgrade = 10;
$student2rawgrade = 20;
- list($course, $assignment, $student1, $student2, $teacher, $parent) = $this->load_test_data($assignmentname, $student1rawgrade, $student2rawgrade);
- $assigment_cm = get_coursemodule_from_id('assign', $assignment->id, 0, false, MUST_EXIST);
+ list($course, $assignment, $student1, $student2, $teacher, $parent) =
+ $this->load_test_data($assignmentname, $student1rawgrade, $student2rawgrade);
+ $assigmentcm = get_coursemodule_from_id('assign', $assignment->id, 0, false, MUST_EXIST);
$this->setUser($teacher);
- // Teacher updating grade item information
+ // Teacher updating grade item information.
$changedmax = 93;
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array(),
array('grademax' => $changedmax)
$grades = grade_get_grades($course->id, 'mod', 'assign', $assignment->id);
$this->assertTrue($grades->items[0]->grademax == $changedmax);
- // Teacher updating 1 student grade
+ // Teacher updating 1 student grade.
$student1grade = 23;
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array(array('studentid' => $student1->id, 'grade' => $student1grade))
);
$grades = grade_get_grades($course->id, 'mod', 'assign', $assignment->id, array($student1->id));
$this->assertTrue($grades->items[0]->grades[$student1->id]->grade == $student1grade);
- // Teacher updating multiple student grades
+ // Teacher updating multiple student grades.
$student1grade = 11;
$student2grade = 13;
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array(
array('studentid' => $student1->id, 'grade' => $student1grade),
$this->assertTrue($grades->items[0]->grades[$student1->id]->grade == $student1grade);
$this->assertTrue($grades->items[0]->grades[$student2->id]->grade == $student2grade);
- // Student attempting to update their own grade (should fail)
+ // Student attempting to update their own grade (should fail).
$this->setUser($student1);
try {
$student1grade = 17;
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array( array('studentid' => $student1->id, 'grade' => $student1grade))
);
$this->assertTrue(true);
}
- // Parent attempting to update their child's grade (should fail)
+ // Parent attempting to update their child's grade (should fail).
$this->setUser($parent);
try {
$student1grade = 13;
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array( array('studentid' => $student1->id, 'grade' => $student1grade))
);
// Student trying to hide a grade item (should fail).
$this->setUser($student1);
try {
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array(),
array('hidden' => 1)
}
// Give the student role 'moodle/grade:hide' and they should now be able to hide the grade item.
- $studentrole = $DB->get_record('role', array('shortname'=>'student'));
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
$coursecontext = context_course::instance($course->id);
assign_capability('moodle/grade:hide', CAP_ALLOW, $studentrole->id, $coursecontext->id);
accesslib_clear_all_caches_for_unit_testing();
$grades = grade_get_grades($course->id, 'mod', 'assign', $assignment->id);
$this->assertTrue($grades->items[0]->hidden == 0);
- $result = core_grade_external::update_grades(
+ $result = core_grades_external::update_grades(
'test',
$course->id,
'mod_assign',
- $assigment_cm->id,
+ $assigmentcm->id,
0,
array(),
array('hidden' => 1)
+++ /dev/null
-This files describes API changes in /grade/*,
-information provided here is intended especially for developers.
-
-
-=== 2.7.0 ===
-* The class core_grade_external in grade/externallib.php has been renamed to core_grading_external.
- grade/externallib.php is concerned with the grading API not the grades API.
- The change was necessary to avoid a duplicate class name with core_grade_external in lib/grade/externallib.php.
'type' => 'read',
'capabilities'=> 'moodle/cohort:view',
),
- // === grade related functions ===
-
- 'core_grade_get_grades' => array(
- 'classname' => 'core_grade_external',
- 'methodname' => 'get_grades',
- 'classpath' => 'lib/grade/externallib.php',
- 'description' => 'Returns grade item details and optionally student grades.',
- 'type' => 'read',
- 'capabilities'=> 'moodle/grade:view, moodle/grade:viewall',
- ),
-
- 'core_grade_update_grades' => array(
- 'classname' => 'core_grade_external',
- 'methodname' => 'update_grades',
- 'classpath' => 'lib/grade/externallib.php',
- 'description' => 'Update a grade item and associated student grades.',
- 'type' => 'write',
- 'capabilities'=> '',
+ // Grade related functions.
+
+ 'core_grades_get_grades' => array(
+ 'classname' => 'core_grades_external',
+ 'methodname' => 'get_grades',
+ 'classpath' => 'grade/externallib.php',
+ 'description' => 'Returns grade item details and optionally student grades.',
+ 'type' => 'read',
+ 'capabilities' => 'moodle/grade:view, moodle/grade:viewall',
+ ),
+
+ 'core_grades_update_grades' => array(
+ 'classname' => 'core_grades_external',
+ 'methodname' => 'update_grades',
+ 'classpath' => 'grade/externallib.php',
+ 'description' => 'Update a grade item and associated student grades.',
+ 'type' => 'write',
+ 'capabilities' => '',
),
// === group related functions ===
+++ /dev/null
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
-
-
-/**
- * External grade API
- *
- * @package core_grade
- * @category external
- * @copyright 2012 Andrew Davis
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require_once("$CFG->libdir/externallib.php");
-
-/**
- * Grade external functions
- *
- * @package core_grade
- * @category external
- * @copyright 2012 Andrew Davis
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @since Moodle 2.6
- */
-class core_grade_external extends external_api {
- /**
- * Returns description of method parameters
- *
- * @return external_function_parameters
- * @since Moodle 2.6
- */
- public static function get_grades_parameters() {
- return new external_function_parameters(
- array(
- 'courseid' => new external_value(PARAM_INT, 'id of course'),
- 'component' => new external_value(PARAM_COMPONENT, 'A component, for example mod_forum or mod_quiz', VALUE_DEFAULT, ''),
- 'activityid' => new external_value(PARAM_INT, 'The activity ID', VALUE_DEFAULT, null),
- 'userids' => new external_multiple_structure(
- new external_value(PARAM_INT, 'user ID'), 'An array of user IDs, leave empty to just retrieve grade item information', VALUE_DEFAULT, array()
- )
- )
- );
- }
-
- /**
- * Retrieve grade items and, optionally, student grades
- *
- * @param array $grades array of grade information
- * @return array of newly created groups
- * @since Moodle 2.6
- */
- public static function get_grades($courseid, $component = null, $activityid = null, $userids = array()) {
- global $CFG, $USER, $DB;
- require_once("$CFG->libdir/gradelib.php");
-
- $params = self::validate_parameters(self::get_grades_parameters(),
- array('courseid' => $courseid, 'component' => $component, 'activityid' => $activityid, 'userids' => $userids));
-
- $coursecontext = context_course::instance($params['courseid']);
-
- try {
- self::validate_context($coursecontext);
- } catch (Exception $e) {
- $exceptionparam = new stdClass();
- $exceptionparam->message = $e->getMessage();
- $exceptionparam->courseid = $params['courseid'];
- throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
- }
-
- $course = $DB->get_record('course', array('id' => $params['courseid']));
-
- $access = false;
- if (has_capability('moodle/grade:viewall', $coursecontext)) {
- // Can view all user's grades in this course.
- $access = true;
-
- } else if ($course->showgrades && count($params['userids']) == 1) {
- // Course showgrades == students/parents can access grades.
-
- if ($params['userids'][0] == $USER->id and has_capability('moodle/grade:view', $coursecontext)) {
- // Student can view their own grades in this course.
- $access = true;
-
- } else if (has_capability('moodle/grade:viewall', context_user::instance($params['userids'][0]))) {
- // User can view the grades of this user. Parent most probably.
- $access = true;
- }
- }
-
- if (!$access) {
- throw new moodle_exception('nopermissiontoviewgrades', 'error');
- }
-
- $itemtype = null;
- $itemmodule = null;
- if (!empty($params['component'])) {
- list($itemtype, $itemmodule) = normalize_component($params['component']);
- }
-
- $cm = null;
- if (!empty($itemmodule) && !empty($activityid)) {
- if (! $cm = get_coursemodule_from_id($itemmodule, $activityid)) {
- throw new moodle_exception('invalidcoursemodule');
- }
- }
-
- $cminstanceid = null;
- if (!empty($cm)) {
- $cminstanceid = $cm->instance;
- }
- $grades = grade_get_grades($params['courseid'], $itemtype, $itemmodule, $cminstanceid, $params['userids']);
-
- $activity_instances = null;
- if (empty($cm)) {
- // If we're dealing with multiple activites load all the module info.
- $modinfo = get_fast_modinfo($params['courseid']);
- $activity_instances = $modinfo->get_instances();
- }
-
- foreach ($grades->items as $gradeitem) {
- if (!empty($cm)) {
- // If they only requested one activity we will already have the cm.
- $modulecm = $cm;
- } else if (!empty($gradeitem->itemmodule)) {
- $modulecm = $activity_instances[$gradeitem->itemmodule][$gradeitem->iteminstance];
- } else {
- // Course grade item.
- continue;
- }
-
- // Make student feedback ready for output.
- foreach ($gradeitem->grades as $studentgrade) {
- if (!empty($studentgrade->feedback)) {
- list($studentgrade->feedback, $categoryinfo->feedbackformat) =
- external_format_text($studentgrade->feedback, $studentgrade->feedbackformat,
- $modulecm->id, $params['component'], 'feedback', null);
- }
- }
- }
-
- // Convert from objects to arrays so all web service clients are supported.
- // While we're doing that we also remove grades the current user can't see due to hiding
- $grades_array = array();
- $canviewhidden = has_capability('moodle/grade:viewhidden', context_course::instance($params['courseid']));
-
- $grades_array['items'] = array();
- foreach ($grades->items as $grade_item) {
- // Switch the stdClass instance for a grade item instance so we can call is_hidden() and use the ID.
- $grade_item_instance = self::get_grade_item($course->id, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, 0);
- if (!$canviewhidden && $grade_item_instance->is_hidden()) {
- continue;
- }
- $grade_item_array = (array)$grade_item;
- $grade_item_array['grades'] = array();
-
- if (!empty($grade_item->grades)) {
- foreach ($grade_item->grades as $studentid => $studentgrade) {
- $grade_grade_instance = grade_grade::fetch(
- array(
- 'userid' => $studentid,
- 'itemid' => $grade_item_instance->id
- )
- );
- if (!$canviewhidden && $grade_grade_instance->is_hidden()) {
- continue;
- }
- $grade_item_array['grades'][$studentid] = (array)$studentgrade;
- // Add the student ID as some WS clients can't access the array key.
- $grade_item_array['grades'][$studentid]['userid'] = $studentid;
- }
- }
-
- // If they requested grades for multiple activities load the cm object now.
- $modulecm = $cm;
- if (empty($modulecm) && !empty($grade_item_instance->itemmodule)) {
- $modulecm = $activity_instances[$grade_item_instance->itemmodule][$grade_item_instance->iteminstance];
- }
- if ($grade_item_instance->itemtype == 'course') {
- $grades_array['items']['course'] = $grade_item_array;
- $grades_array['items']['course']['activityid'] = 'course';
- } else {
- $grades_array['items'][$modulecm->id] = $grade_item_array;
- // Add the activity ID as some WS clients can't access the array key.
- $grades_array['items'][$modulecm->id]['activityid'] = $modulecm->id;
- }
- }
-
- $grades_array['outcomes'] = array();
- foreach ($grades->outcomes as $outcome) {
- $modulecm = $cm;
- if (empty($modulecm)) {
- $modulecm = $activity_instances[$outcome->itemmodule][$outcome->iteminstance];
- }
- $grades_array['outcomes'][$modulecm->id] = (array)$outcome;
- $grades_array['outcomes'][$modulecm->id]['activityid'] = $modulecm->id;
-
- $grades_array['outcomes'][$modulecm->id]['grades'] = array();
- if (!empty($outcome->grades)) {
- foreach ($outcome->grades as $studentid => $studentgrade) {
- if (!$canviewhidden) {
- // Need to load the grade_grade object to check visibility.
- $grade_item_instance = self::get_grade_item($course->id, $outcome->itemtype, $outcome->itemmodule, $outcome->iteminstance, $outcome->itemnumber);
- $grade_grade_instance = grade_grade::fetch(
- array(
- 'userid' => $studentid,
- 'itemid' => $grade_item_instance->id
- )
- );
- // The grade grade may be legitimately missing if the student has no grade.
- if (!empty($grade_grade_instance) && $grade_grade_instance->is_hidden()) {
- continue;
- }
- }
- $grades_array['outcomes'][$modulecm->id]['grades'][$studentid] = (array)$studentgrade;
-
- // Add the student ID into the grade structure as some WS clients can't access the key.
- $grades_array['outcomes'][$modulecm->id]['grades'][$studentid]['userid'] = $studentid;
- }
- }
- }
-
- return $grades_array;
- }
-
- private static function get_grade_item($courseid, $itemtype, $itemmodule = null, $iteminstance = null, $itemnumber = null) {
- $grade_item_instance = null;
- if ($itemtype == 'course') {
- $grade_item_instance = grade_item::fetch(array('courseid' => $courseid, 'itemtype' => $itemtype));
- } else {
- $grade_item_instance = grade_item::fetch(array('courseid' => $courseid, 'itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'itemnumber' => $itemnumber));
- }
- return $grade_item_instance;
- }
-
- /**
- * Returns description of method result value
- *
- * @return external_description
- * @since Moodle 2.6
- */
- public static function get_grades_returns() {
- return new external_single_structure(
- array(
- 'items' => new external_multiple_structure(
- new external_single_structure(
- array(
- 'activityid' => new external_value(PARAM_ALPHANUM, 'The ID of the activity or "course" for the course grade item'),
- 'itemnumber' => new external_value(PARAM_INT, 'Will be 0 unless the module has multiple grades'),
- 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale or 0'),
- 'name' => new external_value(PARAM_RAW, 'The module name'),
- 'grademin' => new external_value(PARAM_FLOAT, 'Minimum grade'),
- 'grademax' => new external_value(PARAM_FLOAT, 'Maximum grade'),
- 'gradepass' => new external_value(PARAM_FLOAT, 'The passing grade threshold'),
- 'locked' => new external_value(PARAM_BOOL, 'Is the grade item locked?'),
- 'hidden' => new external_value(PARAM_BOOL, 'Is the grade item hidden?'),
- 'grades' => new external_multiple_structure(
- new external_single_structure(
- array(
- 'userid' => new external_value(PARAM_INT, 'Student ID'),
- 'grade' => new external_value(PARAM_FLOAT, 'Student grade'),
- 'locked' => new external_value(PARAM_BOOL, 'Is the student\'s grade locked?'),
- 'hidden' => new external_value(PARAM_BOOL, 'Is the student\'s grade hidden?'),
- 'overridden' => new external_value(PARAM_BOOL, 'Is the student\'s grade overridden?'),
- 'feedback' => new external_value(PARAM_RAW, 'Feedback from the grader'),
- 'feedbackformat' => new external_value(PARAM_INT, 'The format of the feedback'),
- 'usermodified' => new external_value(PARAM_INT, 'The ID of the last user to modify this student grade'),
- 'datesubmitted' => new external_value(PARAM_INT, 'A timestamp indicating when the student submitted the activity'),
- 'dategraded' => new external_value(PARAM_INT, 'A timestamp indicating when the assignment was grades'),
- 'str_grade' => new external_value(PARAM_RAW, 'A string representation of the grade'),
- 'str_long_grade' => new external_value(PARAM_RAW, 'A nicely formatted string representation of the grade'),
- 'str_feedback' => new external_value(PARAM_TEXT, 'A string representation of the feedback from the grader'),
- )
- )
- ),
- )
- )
- ),
- 'outcomes' => new external_multiple_structure(
- new external_single_structure(
- array(
- 'activityid' => new external_value(PARAM_ALPHANUM, 'The ID of the activity or "course" for the course grade item'),
- 'itemnumber' => new external_value(PARAM_INT, 'Will be 0 unless the module has multiple grades'),
- 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale or 0'),
- 'name' => new external_value(PARAM_RAW, 'The module name'),
- 'locked' => new external_value(PARAM_BOOL, 'Is the grade item locked?'),
- 'hidden' => new external_value(PARAM_BOOL, 'Is the grade item hidden?'),
- 'grades' => new external_multiple_structure(
- new external_single_structure(
- array(
- 'userid' => new external_value(PARAM_INT, 'Student ID'),
- 'grade' => new external_value(PARAM_FLOAT, 'Student grade'),
- 'locked' => new external_value(PARAM_BOOL, 'Is the student\'s grade locked?'),
- 'hidden' => new external_value(PARAM_BOOL, 'Is the student\'s grade hidden?'),
- 'feedback' => new external_value(PARAM_RAW, 'Feedback from the grader'),
- 'feedbackformat' => new external_value(PARAM_INT, 'The feedback format'),
- 'usermodified' => new external_value(PARAM_INT, 'The ID of the last user to modify this student grade'),
- 'str_grade' => new external_value(PARAM_RAW, 'A string representation of the grade'),
- 'str_feedback' => new external_value(PARAM_TEXT, 'A string representation of the feedback from the grader'),
- )
- )
- ),
- )
- ), 'An array of outcomes associated with the grade items', VALUE_OPTIONAL
- )
- )
- );
-
- }
-
- /**
- * Returns description of method parameters
- *
- * @return external_function_parameters
- * @since Moodle 2.6
- */
- public static function update_grades_parameters() {
- return new external_function_parameters(
- array(
- 'source' => new external_value(PARAM_TEXT, 'The source of the grade update'),
- 'courseid' => new external_value(PARAM_INT, 'id of course'),
- 'component' => new external_value(PARAM_COMPONENT, 'A component, for example mod_forum or mod_quiz'),
- 'activityid' => new external_value(PARAM_INT, 'The activity ID'),
- 'itemnumber' => new external_value(PARAM_INT, 'grade item ID number for modules that have multiple grades. Typically this is 0.'),
- 'grades' => new external_multiple_structure(
- new external_single_structure(
- array(
- 'studentid' => new external_value(PARAM_INT, 'Student ID'),
- 'grade' => new external_value(PARAM_FLOAT, 'Student grade'),
- 'str_feedback' => new external_value(PARAM_TEXT, 'A string representation of the feedback from the grader', VALUE_OPTIONAL),
- )
- ), 'Any student grades to alter', VALUE_OPTIONAL),
- 'itemdetails' => new external_single_structure(
- array(
- 'itemname' => new external_value(PARAM_ALPHANUMEXT, 'The grade item name', VALUE_OPTIONAL),
- 'idnumber' => new external_value(PARAM_INT, 'Arbitrary ID provided by the module responsible for the grade item', VALUE_OPTIONAL),
- 'gradetype' => new external_value(PARAM_INT, 'The type of grade (0 = none, 1 = value, 2 = scale, 3 = text)', VALUE_OPTIONAL),
- 'grademax' => new external_value(PARAM_FLOAT, 'Maximum grade allowed', VALUE_OPTIONAL),
- 'grademin' => new external_value(PARAM_FLOAT, 'Minimum grade allowed', VALUE_OPTIONAL),
- 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale being is used', VALUE_OPTIONAL),
- 'multfactor' => new external_value(PARAM_FLOAT, 'Multiply all grades by this number', VALUE_OPTIONAL),
- 'plusfactor' => new external_value(PARAM_FLOAT, 'Add this to all grades', VALUE_OPTIONAL),
- 'deleted' => new external_value(PARAM_BOOL, 'True if the grade item should be deleted', VALUE_OPTIONAL),
- 'hidden' => new external_value(PARAM_BOOL, 'True if the grade item is hidden', VALUE_OPTIONAL),
- ), 'Any grade item settings to alter', VALUE_OPTIONAL
- )
- )
- );
- }
-
- /**
- * Update a grade item and, optionally, student grades
- *
- * @param array $grade array of grade information
- * @since Moodle 2.6
- */
- public static function update_grades($source, $courseid, $component, $activityid, $itemnumber, $grades = array(), $itemdetails = array()) {
- global $CFG;
-
- require_once("$CFG->libdir/gradelib.php");
-
- $params = self::validate_parameters(
- self::update_grades_parameters(),
- array(
- 'source' => $source,
- 'courseid' => $courseid,
- 'component' => $component,
- 'activityid' => $activityid,
- 'itemnumber' => $itemnumber,
- 'grades' => $grades,
- 'itemdetails' => $itemdetails
- )
- );
-
- list($itemtype, $itemmodule) = normalize_component($params['component']);
-
- if (! $cm = get_coursemodule_from_id($itemmodule, $activityid)) {
- throw new moodle_exception('invalidcoursemodule');
- }
- $iteminstance = $cm->instance;
-
- $coursecontext = context_course::instance($params['courseid']);
-
- try {
- self::validate_context($coursecontext);
- } catch (Exception $e) {
- $exceptionparam = new stdClass();
- $exceptionparam->message = $e->getMessage();
- $exceptionparam->courseid = $params['courseid'];
- throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
- }
-
- $hidinggrades = false;
- $editinggradeitem = false;
- $editinggrades = false;
-
- $gradestructure = array();
- foreach ($grades as $grade) {
- $editinggrades = true;
- $gradestructure[ $grade['studentid'] ] = array('userid' => $grade['studentid'], 'rawgrade' => $grade['grade']);
- }
- if (!empty($params['itemdetails'])) {
- if (isset($params['itemdetails']['hidden'])) {
- $hidinggrades = true;
- } else {
- $editinggradeitem = true;
- }
- }
-
- if ($editinggradeitem && !has_capability('moodle/grade:manage', $coursecontext)) {
- throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null, 'moodle/grade:manage required to edit grade information');
- }
- if ($hidinggrades && !has_capability('moodle/grade:hide', $coursecontext) && !has_capability('moodle/grade:hide', $coursecontext)) {
- throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null, 'moodle/grade:hide required to hide grade items');
- }
- if ($editinggrades && !has_capability('moodle/grade:edit', $coursecontext)) {
- throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null, 'moodle/grade:edit required to edit grades');
- }
-
- return grade_update($params['source'], $params['courseid'], $itemtype, $itemmodule, $iteminstance, $itemnumber, $gradestructure, $params['itemdetails']);
- }
-
- /**
- * Returns description of method result value
- *
- * @return external_description
- * @since Moodle 2.6
- */
- public static function update_grades_returns() {
- return new external_single_structure(
- array (
- 'result' => new external_value(PARAM_INT, 'A value like ' . GRADE_UPDATE_OK . ' => OK, ' . GRADE_UPDATE_FAILED . ' => FAILED as defined in lib/grade/constants.php')
- )
- );
- }
-}
}
}
- $params = array('courseid'=>$courseid);
+ $params = array('courseid' => $courseid);
if (!empty($itemtype)) {
$params['itemtype'] = $itemtype;
}