From 5d62e813ab39f6aa5c0eb357a97da549c94c6a80 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Thu, 5 Feb 2015 13:32:22 +0100 Subject: [PATCH] MDL-48730 webservices: New ws core_group_get_course_user_groups --- group/externallib.php | 109 +++++++++++++++++++++++++++++++ group/tests/externallib_test.php | 88 +++++++++++++++++++++++++ lib/db/services.php | 12 +++- version.php | 2 +- 4 files changed, 209 insertions(+), 2 deletions(-) diff --git a/group/externallib.php b/group/externallib.php index f02b748c1fd..45eadb3f394 100644 --- a/group/externallib.php +++ b/group/externallib.php @@ -1154,6 +1154,115 @@ class core_group_external extends external_api { return null; } + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 2.9 + */ + public static function get_course_user_groups_parameters() { + return new external_function_parameters( + array( + 'courseid' => new external_value(PARAM_INT, 'id of course'), + 'userid' => new external_value(PARAM_INT, 'id of user'), + 'groupingid' => new external_value(PARAM_INT, 'returns only groups in the specified grouping', VALUE_DEFAULT, 0) + ) + ); + } + + /** + * Get all groups in the specified course for the specified user. + * + * @throws moodle_exception + * @param int $courseid id of course. + * @param int $userid id of user. + * @param int $groupingid optional returns only groups in the specified grouping. + * @return array of group objects (id, name, description, format) and possible warnings. + * @since Moodle 2.9 + */ + public static function get_course_user_groups($courseid, $userid, $groupingid = 0) { + global $USER; + + // Warnings array, it can be empty at the end but is mandatory. + $warnings = array(); + + $params = array( + 'courseid' => $courseid, + 'userid' => $userid, + 'groupingid' => $groupingid + ); + $params = self::validate_parameters(self::get_course_user_groups_parameters(), $params); + $courseid = $params['courseid']; + $userid = $params['userid']; + $groupingid = $params['groupingid']; + + // Validate course and user. get_course throws an exception if the course does not exists. + $course = get_course($courseid); + $user = core_user::get_user($userid, 'id', MUST_EXIST); + + // Security checks. + $context = context_course::instance($course->id); + self::validate_context($context); + + // Check if we have permissions for retrieve the information. + if ($user->id != $USER->id) { + if (!has_capability('moodle/course:managegroups', $context)) { + throw new moodle_exception('accessdenied', 'admin'); + } + // Validate if the user is enrolled in the course. + if (!is_enrolled($context, $user->id)) { + // We return a warning because the function does not fail for not enrolled users. + $warning['item'] = 'course'; + $warning['itemid'] = $course->id; + $warning['warningcode'] = '1'; + $warning['message'] = "User $user->id is not enrolled in course $course->id"; + $warnings[] = $warning; + } + } + + $usergroups = array(); + if (empty($warnings)) { + $groups = groups_get_all_groups($course->id, $user->id, 0, 'g.id, g.name, g.description, g.descriptionformat'); + + foreach ($groups as $group) { + list($group->description, $group->descriptionformat) = + external_format_text($group->description, $group->descriptionformat, + $context->id, 'group', 'description', $group->id); + $usergroups[] = (array)$group; + } + } + + $results = array( + 'groups' => $usergroups, + 'warnings' => $warnings + ); + return $results; + } + + /** + * Returns description of method result value. + * + * @return external_description A single structure containing groups and possible warnings. + * @since Moodle 2.9 + */ + public static function get_course_user_groups_returns() { + return new external_single_structure( + array( + 'groups' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'group record id'), + 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'), + 'description' => new external_value(PARAM_RAW, 'group description text'), + 'descriptionformat' => new external_format_value('description') + ) + ) + ), + 'warnings' => new external_warnings(), + ) + ); + } + } /** diff --git a/group/tests/externallib_test.php b/group/tests/externallib_test.php index d3ca01ec3c2..a65d9308a49 100644 --- a/group/tests/externallib_test.php +++ b/group/tests/externallib_test.php @@ -285,4 +285,92 @@ class core_group_externallib_testcase extends externallib_advanced_testcase { $this->assertEquals($dbgroup->courseid, $groupcourseid); } } + + /** + * Test get_groups + */ + public function test_get_course_user_groups() { + global $DB; + + $this->resetAfterTest(true); + + $student1 = self::getDataGenerator()->create_user(); + $student2 = self::getDataGenerator()->create_user(); + $teacher = self::getDataGenerator()->create_user(); + + $course = self::getDataGenerator()->create_course(); + $emptycourse = self::getDataGenerator()->create_course(); + + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id); + + $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); + $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id); + $this->getDataGenerator()->enrol_user($teacher->id, $emptycourse->id, $teacherrole->id); + + $group1data = array(); + $group1data['courseid'] = $course->id; + $group1data['name'] = 'Group Test 1'; + $group1data['description'] = 'Group Test 1 description'; + $group2data = array(); + $group2data['courseid'] = $course->id; + $group2data['name'] = 'Group Test 2'; + $group2data['description'] = 'Group Test 2 description'; + $group1 = self::getDataGenerator()->create_group($group1data); + $group2 = self::getDataGenerator()->create_group($group2data); + + groups_add_member($group1->id, $student1->id); + groups_add_member($group1->id, $student2->id); + groups_add_member($group2->id, $student1->id); + + $this->setUser($student1); + + $groups = core_group_external::get_course_user_groups($course->id, $student1->id); + $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups); + // Check that I see my groups. + $this->assertCount(2, $groups['groups']); + + $this->setUser($student2); + $groups = core_group_external::get_course_user_groups($course->id, $student2->id); + $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups); + // Check that I see my groups. + $this->assertCount(1, $groups['groups']); + + $this->assertEquals($group1data['name'], $groups['groups'][0]['name']); + $this->assertEquals($group1data['description'], $groups['groups'][0]['description']); + + $this->setUser($teacher); + $groups = core_group_external::get_course_user_groups($course->id, $student1->id); + $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups); + // Check that a teacher can see student groups. + $this->assertCount(2, $groups['groups']); + + $groups = core_group_external::get_course_user_groups($course->id, $student2->id); + $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups); + // Check that a teacher can see student groups. + $this->assertCount(1, $groups['groups']); + + // Check permissions. + $this->setUser($student1); + try { + $groups = core_group_external::get_course_user_groups($course->id, $student2->id); + } catch (moodle_exception $e) { + $this->assertEquals('accessdenied', $e->errorcode); + } + + try { + $groups = core_group_external::get_course_user_groups($emptycourse->id, $student2->id); + } catch (moodle_exception $e) { + $this->assertEquals('requireloginerror', $e->errorcode); + } + + $this->setUser($teacher); + // Check warnings. + $groups = core_group_external::get_course_user_groups($emptycourse->id, $student1->id); + $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups); + $this->assertCount(1, $groups['warnings']); + + } + } diff --git a/lib/db/services.php b/lib/db/services.php index 9aa27c11d66..803b13b7b26 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -303,6 +303,15 @@ $functions = array( 'type' => 'write', ), + 'core_group_get_course_user_groups' => array( + 'classname' => 'core_group_external', + 'methodname' => 'get_course_user_groups', + 'classpath' => 'group/externallib.php', + 'description' => 'Returns all groups in specified course for the specified user.', + 'type' => 'read', + 'capabilities' => 'moodle/course:managegroups', + ), + // === file related functions === 'moodle_file_get_files' => array( @@ -985,7 +994,8 @@ $services = array( 'core_message_get_contacts', 'core_message_search_contacts', 'core_message_get_blocked_users', - 'gradereport_user_get_grades_table' + 'gradereport_user_get_grades_table', + 'core_group_get_course_user_groups' ), 'enabled' => 0, 'restrictedusers' => 0, diff --git a/version.php b/version.php index 98b3972cd71..31ec4fc87a6 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015021900.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2015021900.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.