diff --git a/mod/workshop/classes/external.php b/mod/workshop/classes/external.php index 220b216a784..8ddb0843bbb 100644 --- a/mod/workshop/classes/external.php +++ b/mod/workshop/classes/external.php @@ -1540,4 +1540,96 @@ class mod_workshop_external extends external_api { ) ); } + + /** + * Returns the description of the external function parameters. + * + * @return external_external_function_parameters + * @since Moodle 3.4 + */ + public static function get_grades_parameters() { + return new external_function_parameters ( + array( + 'workshopid' => new external_value(PARAM_INT, 'Workshop instance id.'), + 'userid' => new external_value(PARAM_INT, 'User id (empty or 0 for current user).', VALUE_DEFAULT, 0), + ) + ); + } + + /** + * Returns the grades information for the given workshop and user. + * + * @param int $workshopid workshop instance id + * @param int $userid user id + * @return array of warnings and the user plan + * @since Moodle 3.4 + * @throws moodle_exception + */ + public static function get_grades($workshopid, $userid = 0) { + global $USER; + + $params = array( + 'workshopid' => $workshopid, + 'userid' => $userid, + ); + $params = self::validate_parameters(self::get_grades_parameters(), $params); + $warnings = array(); + + 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('mod/workshop:viewallassessments', $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; + } + + $finalgrades = $workshop->get_gradebook_grades($userid); + + $result = array('warnings' => $warnings); + if ($finalgrades !== false) { + if (!empty($finalgrades->submissiongrade)) { + if (is_numeric($finalgrades->submissiongrade->grade)) { + $result['submissionrawgrade'] = $finalgrades->submissiongrade->grade; + } + $result['submissionlongstrgrade'] = $finalgrades->submissiongrade->str_long_grade; + $result['submissiongradehidden'] = $finalgrades->submissiongrade->hidden; + } + if (!empty($finalgrades->assessmentgrade)) { + if (is_numeric($finalgrades->assessmentgrade->grade)) { + $result['assessmentrawgrade'] = $finalgrades->assessmentgrade->grade; + } + $result['assessmentlongstrgrade'] = $finalgrades->assessmentgrade->str_long_grade; + $result['assessmentgradehidden'] = $finalgrades->assessmentgrade->hidden; + } + } + + return $result; + } + + /** + * Returns description of method result value. + * + * @return external_single_structure + * @since Moodle 3.4 + */ + public static function get_grades_returns() { + return new external_single_structure( + array( + 'assessmentrawgrade' => new external_value(PARAM_FLOAT, 'The assessment raw (numeric) grade.', VALUE_OPTIONAL), + 'assessmentlongstrgrade' => new external_value(PARAM_NOTAGS, 'The assessment string grade.', VALUE_OPTIONAL), + 'assessmentgradehidden' => new external_value(PARAM_BOOL, 'Whether the grade is hidden or not.', VALUE_OPTIONAL), + 'submissionrawgrade' => new external_value(PARAM_FLOAT, 'The submission raw (numeric) grade.', VALUE_OPTIONAL), + 'submissionlongstrgrade' => new external_value(PARAM_NOTAGS, 'The submission string grade.', VALUE_OPTIONAL), + 'submissiongradehidden' => new external_value(PARAM_BOOL, 'Whether the grade is hidden or not.', VALUE_OPTIONAL), + 'warnings' => new external_warnings(), + ) + ); + } } diff --git a/mod/workshop/db/services.php b/mod/workshop/db/services.php index d262d1598a9..06aabc616d9 100644 --- a/mod/workshop/db/services.php +++ b/mod/workshop/db/services.php @@ -134,4 +134,11 @@ $functions = array( 'type' => 'write', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), + 'mod_workshop_get_grades' => array( + 'classname' => 'mod_workshop_external', + 'methodname' => 'get_grades', + 'description' => 'Returns the assessment and submission grade for the given user.', + 'type' => 'read', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) + ), ); diff --git a/mod/workshop/tests/external_test.php b/mod/workshop/tests/external_test.php index 860abd2210d..870c737590f 100644 --- a/mod/workshop/tests/external_test.php +++ b/mod/workshop/tests/external_test.php @@ -1524,4 +1524,70 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase { } } } + + /** + * Test get_grades. + */ + public function test_get_grades() { + global $DB; + + $timenow = time(); + $submissiongrade = array( + 'userid' => $this->student->id, + 'rawgrade' => 40, + 'feedback' => '', + 'feedbackformat' => 1, + 'datesubmitted' => $timenow, + 'dategraded' => $timenow, + ); + $assessmentgrade = array( + 'userid' => $this->student->id, + 'rawgrade' => 10, + 'feedback' => '', + 'feedbackformat' => 1, + 'datesubmitted' => $timenow, + 'dategraded' => $timenow, + ); + + workshop_grade_item_update($this->workshop, (object) $submissiongrade, (object) $assessmentgrade); + + // First retrieve my grades. + $this->setUser($this->student); + $result = mod_workshop_external::get_grades($this->workshop->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_grades_returns(), $result); + $this->assertCount(0, $result['warnings']); + $this->assertEquals($assessmentgrade['rawgrade'], $result['assessmentrawgrade']); + $this->assertEquals($submissiongrade['rawgrade'], $result['submissionrawgrade']); + $this->assertFalse($result['assessmentgradehidden']); + $this->assertFalse($result['submissiongradehidden']); + $this->assertEquals($assessmentgrade['rawgrade'] . ".00 / 20.00", $result['assessmentlongstrgrade']); + $this->assertEquals($submissiongrade['rawgrade'] . ".00 / 80.00", $result['submissionlongstrgrade']); + + // Second, teacher retrieve user grades. + $this->setUser($this->teacher); + $result = mod_workshop_external::get_grades($this->workshop->id, $this->student->id); + $result = external_api::clean_returnvalue(mod_workshop_external::get_grades_returns(), $result); + $this->assertCount(0, $result['warnings']); + $this->assertEquals($assessmentgrade['rawgrade'], $result['assessmentrawgrade']); + $this->assertEquals($submissiongrade['rawgrade'], $result['submissionrawgrade']); + $this->assertFalse($result['assessmentgradehidden']); + $this->assertFalse($result['submissiongradehidden']); + $this->assertEquals($assessmentgrade['rawgrade'] . ".00 / 20.00", $result['assessmentlongstrgrade']); + $this->assertEquals($submissiongrade['rawgrade'] . ".00 / 80.00", $result['submissionlongstrgrade']); + } + + /** + * Test get_grades_other_student. + */ + public function test_get_grades_other_student() { + global $DB; + + // Create the submission that will be deleted. + $submissionid = $this->create_test_submission($this->student); + + $DB->set_field('workshop', 'phase', workshop::PHASE_CLOSED, array('id' => $this->workshop->id)); + $this->setUser($this->anotherstudentg1); + $this->expectException('moodle_exception'); + mod_workshop_external::get_grades($this->workshop->id, $this->student->id); + } } diff --git a/mod/workshop/version.php b/mod/workshop/version.php index 72263d982b8..94d9d6c8b9e 100644 --- a/mod/workshop/version.php +++ b/mod/workshop/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2017051514; // The current module version (YYYYMMDDXX) +$plugin->version = 2017051515; // The current module version (YYYYMMDDXX) $plugin->requires = 2017050500; // Requires this Moodle version. $plugin->component = 'mod_workshop'; $plugin->cron = 60; // Give as a chance every minute.