MDL-55928 gradereport_user: New WS for retrieve grade items
authorJuan Leyva <juanleyvadelgado@gmail.com>
Mon, 12 Sep 2016 14:14:50 +0000 (15:14 +0100)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Fri, 16 Sep 2016 08:55:14 +0000 (09:55 +0100)
It includes a refactor of the complete externallib.
Previously it was not possible to filter the report by groups.

grade/report/upgrade.txt
grade/report/user/db/services.php
grade/report/user/externallib.php
grade/report/user/tests/externallib_test.php
grade/report/user/version.php
lib/classes/grades_external.php

index 9236fc8..e74ef64 100644 (file)
@@ -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.
index 252e4b8..e134414 100644 (file)
@@ -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),
     )
 );
index 057666c..9ed53bd 100644 (file)
@@ -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.
-     *
-     * @param int $courseid Course Id
-     * @param int $userid   Only this user (optional)
+     * Validate access permissions to the report
      *
-     * @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()
+            )
+        );
+    }
 }
index 2c04c20..02c79e4 100644 (file)
@@ -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&ndash;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&ndash;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&ndash;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']);
     }
 
 }
index a22d175..2c1fa28 100644 (file)
@@ -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)
index f2a0e6d..70af39c 100644 (file)
@@ -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(