diff --git a/grade/report/upgrade.txt b/grade/report/upgrade.txt index 9236fc8196f..e74ef64863d 100644 --- a/grade/report/upgrade.txt +++ b/grade/report/upgrade.txt @@ -1,5 +1,10 @@ This files describes API changes in /grade/report/*, information provided here is intended especially for developers. + +=== 3.2 === +* External function gradereport_user_external::get_grades_table now has an optional groupid parameter. +Is recommended to use this parameter in courses with separate groups or when the user requesting the report is in more than one group. + === 2.9 === * Deprecating grade_report_grader:get_collapsing_icon. * A new web service function gradereport_user_get_grades_table has been added which will allow external system to retrieve grade information ready to be formatted as a table similar to the gradebook user report one. diff --git a/grade/report/user/db/services.php b/grade/report/user/db/services.php index 252e4b89c1a..e1344141a91 100644 --- a/grade/report/user/db/services.php +++ b/grade/report/user/db/services.php @@ -41,5 +41,14 @@ $functions = array( 'type' => 'write', 'capabilities' => 'gradereport/user:view', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + ), + 'gradereport_user_get_grade_items' => array( + 'classname' => 'gradereport_user_external', + 'methodname' => 'get_grade_items', + 'classpath' => 'grade/report/user/externallib.php', + 'description' => 'Returns the complete list of grade items for users in a course', + 'type' => 'read', + 'capabilities' => 'gradereport/user:view', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ) ); diff --git a/grade/report/user/externallib.php b/grade/report/user/externallib.php index 057666cd368..9ed53bd91da 100644 --- a/grade/report/user/externallib.php +++ b/grade/report/user/externallib.php @@ -37,45 +37,32 @@ require_once("$CFG->libdir/externallib.php"); */ class gradereport_user_external extends external_api { - /** - * Describes the parameters for get_grades_table. - * - * @return external_external_function_parameters - * @since Moodle 2.9 - */ - public static function get_grades_table_parameters() { - return new external_function_parameters ( - array( - 'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED), - 'userid' => new external_value(PARAM_INT, 'Return grades only for this user (optional)', VALUE_DEFAULT, 0) - ) - ); - } /** - * Returns a list of grades tables for users in a course. + * Validate access permissions to the report * - * @param int $courseid Course Id - * @param int $userid Only this user (optional) - * - * @return array the grades tables - * @since Moodle 2.9 + * @param int $courseid the courseid + * @param int $userid the user id to retrieve data from + * @param int $groupid the group id + * @return array with the parameters cleaned and other required information + * @since Moodle 3.2 */ - public static function get_grades_table($courseid, $userid = 0) { - global $CFG, $USER; - - $warnings = array(); + protected static function check_report_access($courseid, $userid, $groupid = 0) { + global $USER; // Validate the parameter. $params = self::validate_parameters(self::get_grades_table_parameters(), array( 'courseid' => $courseid, - 'userid' => $userid) - ); + 'userid' => $userid, + 'groupid' => $groupid, + ) + ); // Compact/extract functions are not recommended. $courseid = $params['courseid']; $userid = $params['userid']; + $groupid = $params['groupid']; // Function get_course internally throws an exception if the course doesn't exist. $course = get_course($courseid); @@ -93,6 +80,11 @@ class gradereport_user_external extends external_api { } else { $user = core_user::get_user($userid, '*', MUST_EXIST); core_user::require_active_user($user); + // Check if we can view the user group (if any). + // When userid == 0, we are retrieving all the users, we'll check then if a groupid is required. + if (!groups_user_groups_visible($course, $user->id)) { + throw new moodle_exception('notingroup'); + } } $access = false; @@ -109,6 +101,42 @@ class gradereport_user_external extends external_api { throw new moodle_exception('nopermissiontoviewgrades', 'error'); } + if (!empty($groupid)) { + // Determine is the group is visible to user. + if (!groups_group_visible($groupid, $course)) { + throw new moodle_exception('notingroup'); + } + } else { + // Check to see if groups are being used here. + if ($groupmode = groups_get_course_groupmode($course)) { + $groupid = groups_get_course_group($course); + // Determine is the group is visible to user (this is particullary for the group 0). + if (!groups_group_visible($groupid, $course)) { + throw new moodle_exception('notingroup'); + } + } else { + $groupid = 0; + } + } + + return array($params, $course, $context, $user, $groupid); + } + + /** + * Get the report data + * @param stdClass $course course object + * @param stdClass $context context object + * @param stdClass $user user object (it can be null for all the users) + * @param int $userid the user to retrieve data from, 0 for all + * @param int $groupid the group id to filter + * @param bool $tabledata whether to get the table data (true) or the gradeitemdata + * @return array data and possible warnings + * @since Moodle 3.2 + */ + protected static function get_report_data($course, $context, $user, $userid, $groupid, $tabledata = true) { + global $CFG; + + $warnings = array(); // Require files here to save some memory in case validation fails. require_once($CFG->dirroot . '/group/lib.php'); require_once($CFG->libdir . '/gradelib.php'); @@ -122,49 +150,95 @@ class gradereport_user_external extends external_api { array( 'type' => 'report', 'plugin' => 'user', - 'courseid' => $courseid, + 'courseid' => $course->id, 'userid' => $userid) ); - $tables = array(); + $reportdata = array(); // Just one user. if ($user) { - $report = new grade_report_user($courseid, $gpr, $context, $userid); + $report = new grade_report_user($course->id, $gpr, $context, $userid); $report->fill_table(); - $tables[] = array( - 'courseid' => $courseid, + $gradeuserdata = array( + 'courseid' => $course->id, 'userid' => $user->id, 'userfullname' => fullname($user), 'maxdepth' => $report->maxdepth, - 'tabledata' => $report->tabledata ); - + if ($tabledata) { + $gradeuserdata['tabledata'] = $report->tabledata; + } else { + $gradeuserdata['gradeitems'] = $report->gradeitemsdata; + } + $reportdata[] = $gradeuserdata; } else { $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol); $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol); $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context); - $gui = new graded_users_iterator($course); + $gui = new graded_users_iterator($course, null, $groupid); $gui->require_active_enrolment($showonlyactiveenrol); $gui->init(); while ($userdata = $gui->next_user()) { $currentuser = $userdata->user; - $report = new grade_report_user($courseid, $gpr, $context, $currentuser->id); + $report = new grade_report_user($course->id, $gpr, $context, $currentuser->id); $report->fill_table(); - $tables[] = array( - 'courseid' => $courseid, + $gradeuserdata = array( + 'courseid' => $course->id, 'userid' => $currentuser->id, 'userfullname' => fullname($currentuser), 'maxdepth' => $report->maxdepth, - 'tabledata' => $report->tabledata ); + if ($tabledata) { + $gradeuserdata['tabledata'] = $report->tabledata; + } else { + $gradeuserdata['gradeitems'] = $report->gradeitemsdata; + } + $reportdata[] = $gradeuserdata; } $gui->close(); } + return array($reportdata, $warnings); + } + + /** + * Describes the parameters for get_grades_table. + * + * @return external_external_function_parameters + * @since Moodle 2.9 + */ + public static function get_grades_table_parameters() { + return new external_function_parameters ( + array( + 'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED), + 'userid' => new external_value(PARAM_INT, 'Return grades only for this user (optional)', VALUE_DEFAULT, 0), + 'groupid' => new external_value(PARAM_INT, 'Get users from this group only', VALUE_DEFAULT, 0) + ) + ); + } + + /** + * Returns a list of grades tables for users in a course. + * + * @param int $courseid Course Id + * @param int $userid Only this user (optional) + * @param int $groupid Get users from this group only + * + * @return array the grades tables + * @since Moodle 2.9 + */ + public static function get_grades_table($courseid, $userid = 0, $groupid = 0) { + global $CFG, $USER; + + list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid); + $userid = $params['userid']; + + // We pass userid because it can be still 0. + list($tables, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid); $result = array(); $result['tables'] = $tables; @@ -268,7 +342,7 @@ class gradereport_user_external extends external_api { return new external_function_parameters( array( 'courseid' => new external_value(PARAM_INT, 'id of the course'), - 'userid' => new external_value(PARAM_INT, 'id of the user, 0 means current user', VALUE_DEFAULT, 0) + 'userid' => new external_value(PARAM_INT, 'id of the user, 0 means current user', VALUE_DEFAULT, 0), ) ); } @@ -346,4 +420,105 @@ class gradereport_user_external extends external_api { ) ); } + + /** + * Describes the parameters for get_grade_items. + * + * @return external_external_function_parameters + * @since Moodle 3.2 + */ + public static function get_grade_items_parameters() { + return self::get_grades_table_parameters(); + } + + /** + * Returns the complete list of grade items for users in a course. + * + * @param int $courseid Course Id + * @param int $userid Only this user (optional) + * @param int $groupid Get users from this group only + * + * @return array the grades tables + * @since Moodle 3.2 + */ + public static function get_grade_items($courseid, $userid = 0, $groupid = 0) { + global $CFG, $USER; + + list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid); + $userid = $params['userid']; + + // We pass userid because it can be still 0. + list($gradeitems, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid, false); + + foreach ($gradeitems as $gradeitem) { + if (isset($gradeitem['feedback']) and isset($gradeitem['feedbackformat'])) { + list($gradeitem['feedback'], $gradeitem['feedbackformat']) = + external_format_text($gradeitem['feedback'], $gradeitem['feedbackformat'], $context->id); + } + } + + $result = array(); + $result['usergrades'] = $gradeitems; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Describes tget_grade_items return value. + * + * @return external_single_structure + * @since Moodle 3.2 + */ + public static function get_grade_items_returns() { + return new external_single_structure( + array( + 'usergrades' => new external_multiple_structure( + new external_single_structure( + array( + 'courseid' => new external_value(PARAM_INT, 'course id'), + 'userid' => new external_value(PARAM_INT, 'user id'), + 'userfullname' => new external_value(PARAM_TEXT, 'user fullname'), + 'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'), + 'gradeitems' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Grade item id'), + 'itemtype' => new external_value(PARAM_ALPHA, 'Grade item type'), + 'itemmodule' => new external_value(PARAM_PLUGIN, 'Grade item module'), + 'iteminstance' => new external_value(PARAM_INT, 'Grade item instance'), + 'itemnumber' => new external_value(PARAM_INT, 'Grade item item number'), + 'categoryid' => new external_value(PARAM_INT, 'Grade item category id'), + 'outcomeid' => new external_value(PARAM_INT, 'Outcome id'), + 'scaleid' => new external_value(PARAM_INT, 'Scale id'), + 'cmid' => new external_value(PARAM_INT, 'Course module id (if type mod)', VALUE_OPTIONAL), + 'weightraw' => new external_value(PARAM_FLOAT, 'Weight raw', VALUE_OPTIONAL), + 'weightformatted' => new external_value(PARAM_NOTAGS, 'Weight', VALUE_OPTIONAL), + 'status' => new external_value(PARAM_ALPHA, 'Status', VALUE_OPTIONAL), + 'graderaw' => new external_value(PARAM_FLOAT, 'Grade raw', VALUE_OPTIONAL), + 'gradedatesubmitted' => new external_value(PARAM_INT, 'Grade submit date', VALUE_OPTIONAL), + 'gradedategraded' => new external_value(PARAM_INT, 'Grade graded date', VALUE_OPTIONAL), + 'gradehiddenbydate' => new external_value(PARAM_BOOL, 'Grade hidden by date?', VALUE_OPTIONAL), + 'gradeneedsupdate' => new external_value(PARAM_BOOL, 'Grade needs update?', VALUE_OPTIONAL), + 'gradeishidden' => new external_value(PARAM_BOOL, 'Grade is hidden?', VALUE_OPTIONAL), + 'gradeformatted' => new external_value(PARAM_NOTAGS, 'The grade formatted', VALUE_OPTIONAL), + 'grademin' => new external_value(PARAM_FLOAT, 'Grade min', VALUE_OPTIONAL), + 'grademax' => new external_value(PARAM_FLOAT, 'Grade max', VALUE_OPTIONAL), + 'rangeformatted' => new external_value(PARAM_NOTAGS, 'Range formatted', VALUE_OPTIONAL), + 'percentageformatted' => new external_value(PARAM_NOTAGS, 'Percentage', VALUE_OPTIONAL), + 'lettergradeformatted' => new external_value(PARAM_NOTAGS, 'Letter grade', VALUE_OPTIONAL), + 'rank' => new external_value(PARAM_INT, 'Rank in the course', VALUE_OPTIONAL), + 'numusers' => new external_value(PARAM_INT, 'Num users in course', VALUE_OPTIONAL), + 'averageformatted' => new external_value(PARAM_NOTAGS, 'Grade average', VALUE_OPTIONAL), + 'feedback' => new external_value(PARAM_RAW, 'Grade feedback', VALUE_OPTIONAL), + 'feedbackformat' => new external_format_value('feedback'), + ), 'Grade items' + ) + ) + ) + ) + ), + 'warnings' => new external_warnings() + ) + ); + } } diff --git a/grade/report/user/tests/externallib_test.php b/grade/report/user/tests/externallib_test.php index 2c04c2058d0..02c79e4109c 100644 --- a/grade/report/user/tests/externallib_test.php +++ b/grade/report/user/tests/externallib_test.php @@ -49,7 +49,7 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas private function load_data($s1grade, $s2grade) { global $DB; - $course = $this->getDataGenerator()->create_course(); + $course = $this->getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1)); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $student1 = $this->getDataGenerator()->create_user(); @@ -58,10 +58,20 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $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' => 'teacher')); $teacher = $this->getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); + $context = context_course::instance($course->id); + assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $teacherrole->id, $context); + accesslib_clear_all_caches_for_unit_testing(); + + $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); + $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); + groups_add_member($group1->id, $student1->id); + groups_add_member($group1->id, $teacher->id); + groups_add_member($group2->id, $student2->id); + $assignment = $this->getDataGenerator()->create_module('assign', array('name' => "Test assign", 'course' => $course->id)); $modcontext = get_coursemodule_from_instance('assign', $assignment->id, $course->id); $assignment->cmidnumber = $modcontext->id; @@ -71,7 +81,7 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $studentgrades = array($student1->id => $student1grade, $student2->id => $student2grade); assign_grade_item_update($assignment, $studentgrades); - return array($course, $teacher, $student1, $student2); + return array($course, $teacher, $student1, $student2, $assignment); } /** @@ -84,30 +94,26 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $s1grade = 80; $s2grade = 60; - list($course, $teacher, $student1, $student2) = $this->load_data($s1grade, $s2grade); + list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); - // A teacher must see all student grades. + // A teacher must see all student grades (in their group only). $this->setUser($teacher); $studentgrades = gradereport_user_external::get_grades_table($course->id); $studentgrades = external_api::clean_returnvalue(gradereport_user_external::get_grades_table_returns(), $studentgrades); // No warnings returned. - $this->assertTrue(count($studentgrades['warnings']) == 0); + $this->assertCount(0, $studentgrades['warnings']); - // Check that two grades are returned (each for student). - $this->assertTrue(count($studentgrades['tables']) == 2); + // Check that only grades for the student in the teacher group are returned. + $this->assertCount(1, $studentgrades['tables']); // Read returned grades. $studentreturnedgrades = array(); $studentreturnedgrades[$studentgrades['tables'][0]['userid']] = (int) $studentgrades['tables'][0]['tabledata'][1]['grade']['content']; - $studentreturnedgrades[$studentgrades['tables'][1]['userid']] = - (int) $studentgrades['tables'][1]['tabledata'][1]['grade']['content']; - $this->assertEquals($s1grade, $studentreturnedgrades[$student1->id]); - $this->assertEquals($s2grade, $studentreturnedgrades[$student2->id]); } /** @@ -121,7 +127,7 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $s1grade = 80; $s2grade = 60; - list($course, $teacher, $student1, $student2) = $this->load_data($s1grade, $s2grade); + list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); // A user can see his own grades. $this->setUser($student1); @@ -148,7 +154,7 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $s1grade = 80; $s2grade = 60; - list($course, $teacher, $student1, $student2) = $this->load_data($s1grade, $s2grade); + list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); $this->setUser($student2); @@ -156,9 +162,8 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $studentgrade = gradereport_user_external::get_grades_table($course->id, $student1->id); $this->fail('Exception expected due to not perissions to view other user grades.'); } catch (moodle_exception $e) { - $this->assertEquals('nopermissiontoviewgrades', $e->errorcode); + $this->assertEquals('notingroup', $e->errorcode); } - } /** @@ -171,7 +176,7 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas $s1grade = 80; $s2grade = 60; - list($course, $teacher, $student1, $student2) = $this->load_data($s1grade, $s2grade); + list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); // Redirect events to the sink, so we can recover them later. $sink = $this->redirectEvents(); @@ -207,7 +212,152 @@ class gradereport_user_externallib_testcase extends externallib_advanced_testcas } catch (moodle_exception $e) { $this->assertEquals('nopermissiontoviewgrades', $e->errorcode); } + } + /** + * Test get_grades_items function case teacher + */ + public function test_get_grade_items_teacher() { + + $this->resetAfterTest(true); + + $s1grade = 80; + $s2grade = 60; + + list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); + + // A teacher must see all student grades (in their group only). + $this->setUser($teacher); + + grade_set_setting($course->id, 'report_user_showrank', 1); + grade_set_setting($course->id, 'report_user_showpercentage', 1); + grade_set_setting($course->id, 'report_user_showhiddenitems', 1); + grade_set_setting($course->id, 'report_user_showgrade', 1); + grade_set_setting($course->id, 'report_user_showfeedback', 1); + grade_set_setting($course->id, 'report_user_showweight', 1); + grade_set_setting($course->id, 'report_user_showcontributiontocoursetotal', 1); + grade_set_setting($course->id, 'report_user_showlettergrade', 1); + grade_set_setting($course->id, 'report_user_showaverage', 1); + + $studentgrades = gradereport_user_external::get_grade_items($course->id); + $studentgrades = external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); + // No warnings returned. + $this->assertCount(0, $studentgrades['warnings']); + + // Check that only grades for the student in the teacher group are returned. + $this->assertCount(1, $studentgrades['usergrades']); + $this->assertCount(2, $studentgrades['usergrades'][0]['gradeitems']); + + $this->assertEquals($course->id, $studentgrades['usergrades'][0]['courseid']); + $this->assertEquals($student1->id, $studentgrades['usergrades'][0]['userid']); + // Module grades. + $this->assertEquals('mod', $studentgrades['usergrades'][0]['gradeitems'][0]['itemtype']); + $this->assertEquals('assign', $studentgrades['usergrades'][0]['gradeitems'][0]['itemmodule']); + $this->assertEquals($assignment->id, $studentgrades['usergrades'][0]['gradeitems'][0]['iteminstance']); + $this->assertEquals($assignment->cmidnumber, $studentgrades['usergrades'][0]['gradeitems'][0]['cmid']); + $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['itemnumber']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['outcomeid']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['scaleid']); + $this->assertEquals(80, $studentgrades['usergrades'][0]['gradeitems'][0]['graderaw']); + $this->assertEquals('80.00', $studentgrades['usergrades'][0]['gradeitems'][0]['gradeformatted']); + $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['grademin']); + $this->assertEquals(100, $studentgrades['usergrades'][0]['gradeitems'][0]['grademax']); + $this->assertEquals('0–100', $studentgrades['usergrades'][0]['gradeitems'][0]['rangeformatted']); + $this->assertEquals('80.00 %', $studentgrades['usergrades'][0]['gradeitems'][0]['percentageformatted']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['feedback']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradehiddenbydate']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeneedsupdate']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeishidden']); + $this->assertEquals('B-', $studentgrades['usergrades'][0]['gradeitems'][0]['lettergradeformatted']); + $this->assertEquals(1, $studentgrades['usergrades'][0]['gradeitems'][0]['rank']); + $this->assertEquals(2, $studentgrades['usergrades'][0]['gradeitems'][0]['numusers']); + $this->assertEquals(70, $studentgrades['usergrades'][0]['gradeitems'][0]['averageformatted']); + + // Course grades. + $this->assertEquals('course', $studentgrades['usergrades'][0]['gradeitems'][1]['itemtype']); + $this->assertEquals(80, $studentgrades['usergrades'][0]['gradeitems'][1]['graderaw']); + $this->assertEquals('80.00', $studentgrades['usergrades'][0]['gradeitems'][1]['gradeformatted']); + $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][1]['grademin']); + $this->assertEquals(100, $studentgrades['usergrades'][0]['gradeitems'][1]['grademax']); + $this->assertEquals('0–100', $studentgrades['usergrades'][0]['gradeitems'][1]['rangeformatted']); + $this->assertEquals('80.00 %', $studentgrades['usergrades'][0]['gradeitems'][1]['percentageformatted']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][1]['feedback']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradehiddenbydate']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradeneedsupdate']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][1]['gradeishidden']); + $this->assertEquals('B-', $studentgrades['usergrades'][0]['gradeitems'][1]['lettergradeformatted']); + $this->assertEquals(1, $studentgrades['usergrades'][0]['gradeitems'][1]['rank']); + $this->assertEquals(2, $studentgrades['usergrades'][0]['gradeitems'][1]['numusers']); + $this->assertEquals(70, $studentgrades['usergrades'][0]['gradeitems'][1]['averageformatted']); + } + + /** + * Test get_grades_items function case student + */ + public function test_get_grade_items_student() { + + $this->resetAfterTest(true); + + $s1grade = 80; + $s2grade = 60; + + list($course, $teacher, $student1, $student2, $assignment) = $this->load_data($s1grade, $s2grade); + + grade_set_setting($course->id, 'report_user_showrank', 1); + grade_set_setting($course->id, 'report_user_showpercentage', 1); + grade_set_setting($course->id, 'report_user_showgrade', 1); + grade_set_setting($course->id, 'report_user_showfeedback', 1); + grade_set_setting($course->id, 'report_user_showweight', 1); + grade_set_setting($course->id, 'report_user_showcontributiontocoursetotal', 1); + grade_set_setting($course->id, 'report_user_showlettergrade', 1); + grade_set_setting($course->id, 'report_user_showaverage', 1); + + $this->setUser($student1); + + $studentgrades = gradereport_user_external::get_grade_items($course->id, $student1->id); + $studentgrades = external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); + // No warnings returned. + $this->assertCount(0, $studentgrades['warnings']); + + // Check that only grades for the student in the teacher group are returned. + $this->assertCount(1, $studentgrades['usergrades']); + $this->assertCount(2, $studentgrades['usergrades'][0]['gradeitems']); + + $this->assertEquals($course->id, $studentgrades['usergrades'][0]['courseid']); + $this->assertEquals($student1->id, $studentgrades['usergrades'][0]['userid']); + $this->assertEquals('mod', $studentgrades['usergrades'][0]['gradeitems'][0]['itemtype']); + $this->assertEquals('assign', $studentgrades['usergrades'][0]['gradeitems'][0]['itemmodule']); + $this->assertEquals($assignment->id, $studentgrades['usergrades'][0]['gradeitems'][0]['iteminstance']); + $this->assertEquals($assignment->cmidnumber, $studentgrades['usergrades'][0]['gradeitems'][0]['cmid']); + $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['itemnumber']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['outcomeid']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['scaleid']); + $this->assertEquals(80, $studentgrades['usergrades'][0]['gradeitems'][0]['graderaw']); + $this->assertEquals('80.00', $studentgrades['usergrades'][0]['gradeitems'][0]['gradeformatted']); + $this->assertEquals(0, $studentgrades['usergrades'][0]['gradeitems'][0]['grademin']); + $this->assertEquals(100, $studentgrades['usergrades'][0]['gradeitems'][0]['grademax']); + $this->assertEquals('0–100', $studentgrades['usergrades'][0]['gradeitems'][0]['rangeformatted']); + $this->assertEquals('80.00 %', $studentgrades['usergrades'][0]['gradeitems'][0]['percentageformatted']); + $this->assertEmpty($studentgrades['usergrades'][0]['gradeitems'][0]['feedback']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradehiddenbydate']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeneedsupdate']); + $this->assertFalse($studentgrades['usergrades'][0]['gradeitems'][0]['gradeishidden']); + $this->assertEquals('B-', $studentgrades['usergrades'][0]['gradeitems'][0]['lettergradeformatted']); + $this->assertEquals(1, $studentgrades['usergrades'][0]['gradeitems'][0]['rank']); + $this->assertEquals(2, $studentgrades['usergrades'][0]['gradeitems'][0]['numusers']); + $this->assertEquals(70, $studentgrades['usergrades'][0]['gradeitems'][0]['averageformatted']); + + // Hide one grade for the user. + $gradegrade = new grade_grade(array('userid' => $student1->id, + 'itemid' => $studentgrades['usergrades'][0]['gradeitems'][0]['id']), true); + $gradegrade->set_hidden(1); + $studentgrades = gradereport_user_external::get_grade_items($course->id, $student1->id); + $studentgrades = external_api::clean_returnvalue(gradereport_user_external::get_grade_items_returns(), $studentgrades); + + // Check we get only the course final grade. + $this->assertCount(1, $studentgrades['usergrades']); + $this->assertCount(1, $studentgrades['usergrades'][0]['gradeitems']); + $this->assertEquals('course', $studentgrades['usergrades'][0]['gradeitems'][0]['itemtype']); } } diff --git a/grade/report/user/version.php b/grade/report/user/version.php index a22d1757949..2c1fa28c389 100644 --- a/grade/report/user/version.php +++ b/grade/report/user/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2016052300; // The current plugin version (Date: YYYYMMDDXX) +$plugin->version = 2016052301; // The current plugin version (Date: YYYYMMDDXX) $plugin->requires = 2016051900; // Requires this Moodle version $plugin->component = 'gradereport_user'; // Full name of the plugin (used for diagnostics) diff --git a/lib/classes/grades_external.php b/lib/classes/grades_external.php index f2a0e6d3739..70af39c8326 100644 --- a/lib/classes/grades_external.php +++ b/lib/classes/grades_external.php @@ -39,7 +39,7 @@ class core_grades_external extends external_api { * @return external_function_parameters * @since Moodle 2.7 * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more. - * @see gradereport_user_external::get_grades_table for a similar function + * @see gradereport_user_external::get_grade_items for a similar function */ public static function get_grades_parameters() { return new external_function_parameters( @@ -68,7 +68,7 @@ class core_grades_external extends external_api { * @return array Array of grades * @since Moodle 2.7 * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more. - * @see gradereport_user_external::get_grades_table for a similar function + * @see gradereport_user_external::get_grade_items for a similar function */ public static function get_grades($courseid, $component = null, $activityid = null, $userids = array()) { global $CFG, $USER, $DB; @@ -298,7 +298,7 @@ class core_grades_external extends external_api { * @param int $itemnumber Item number * @return grade_item A grade_item instance * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more. - * @see gradereport_user_external::get_grades_table for a similar function + * @see gradereport_user_external::get_grade_items for a similar function */ private static function get_grade_item($courseid, $itemtype, $itemmodule = null, $iteminstance = null, $itemnumber = null) { $gradeiteminstance = null; @@ -318,7 +318,7 @@ class core_grades_external extends external_api { * @return external_description * @since Moodle 2.7 * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more. - * @see gradereport_user_external::get_grades_table for a similar function + * @see gradereport_user_external::get_grade_items for a similar function */ public static function get_grades_returns() { return new external_single_structure(