Merge branch 'MDL-50966-master' of git://github.com/jleyva/moodle
authorDavid Monllao <davidm@moodle.com>
Tue, 15 Sep 2015 08:58:54 +0000 (16:58 +0800)
committerDavid Monllao <davidm@moodle.com>
Tue, 15 Sep 2015 08:58:54 +0000 (16:58 +0800)
group/externallib.php
group/tests/externallib_test.php
lib/db/services.php

index 1f9b739..cac0811 100644 (file)
@@ -1254,7 +1254,8 @@ class core_group_external extends external_api {
                 list($group->description, $group->descriptionformat) =
                     external_format_text($group->description, $group->descriptionformat,
                             $context->id, 'group', 'description', $group->id);
-                $usergroups[] = (array)$group;
+                $group->courseid = $course->id;
+                $usergroups[] = $group;
             }
         }
 
@@ -1274,17 +1275,135 @@ class core_group_external extends external_api {
     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'),
-                            'idnumber' => new external_value(PARAM_RAW, 'id number')
-                        )
-                    )
-                ),
+                'groups' => new external_multiple_structure(self::group_description()),
+                'warnings' => new external_warnings(),
+            )
+        );
+    }
+
+    /**
+     * Create group return value description.
+     *
+     * @return external_single_structure The group description
+     */
+    public static function group_description() {
+        return 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'),
+                'idnumber' => new external_value(PARAM_RAW, 'id number'),
+                'courseid' => new external_value(PARAM_INT, 'course id', VALUE_OPTIONAL),
+            )
+        );
+    }
+
+    /**
+     * Returns description of method parameters
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.0
+     */
+    public static function get_activity_allowed_groups_parameters() {
+        return new external_function_parameters(
+            array(
+                'cmid' => new external_value(PARAM_INT, 'course module id'),
+                'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_OPTIONAL, 0)
+            )
+        );
+    }
+
+    /**
+     * Gets a list of groups that the user is allowed to access within the specified activity.
+     *
+     * @throws moodle_exception
+     * @param int $cmid course module id
+     * @param int $userid id of user.
+     * @return array of group objects (id, name, description, format) and possible warnings.
+     * @since Moodle 3.0
+     */
+    public static function get_activity_allowed_groups($cmid, $userid = 0) {
+        global $USER;
+
+        // Warnings array, it can be empty at the end but is mandatory.
+        $warnings = array();
+
+        $params = array(
+            'cmid' => $cmid,
+            'userid' => $userid
+        );
+        $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
+        $cmid = $params['cmid'];
+        $userid = $params['userid'];
+
+        $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
+
+        // Security checks.
+        $context = context_module::instance($cm->id);
+        $coursecontext = context_course::instance($cm->course);
+        self::validate_context($context);
+
+        if (empty($userid)) {
+            $userid = $USER->id;
+        }
+
+        $user = core_user::get_user($userid, 'id, deleted', MUST_EXIST);
+        if ($user->deleted) {
+            throw new moodle_exception('userdeleted');
+        }
+        if (isguestuser($user)) {
+            throw new moodle_exception('invaliduserid');
+        }
+
+         // 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($coursecontext, $user->id)) {
+                // We return a warning because the function does not fail for not enrolled users.
+                $warning = array();
+                $warning['item'] = 'course';
+                $warning['itemid'] = $cm->course;
+                $warning['warningcode'] = '1';
+                $warning['message'] = "User $user->id is not enrolled in course $cm->course";
+                $warnings[] = $warning;
+            }
+        }
+
+        $usergroups = array();
+        if (empty($warnings)) {
+            $groups = groups_get_activity_allowed_groups($cm, $user->id);
+
+            foreach ($groups as $group) {
+                list($group->description, $group->descriptionformat) =
+                    external_format_text($group->description, $group->descriptionformat,
+                            $coursecontext->id, 'group', 'description', $group->id);
+                $group->courseid = $cm->course;
+                $usergroups[] = $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 3.0
+     */
+    public static function get_activity_allowed_groups_returns() {
+        return new external_single_structure(
+            array(
+                'groups' => new external_multiple_structure(self::group_description()),
                 'warnings' => new external_warnings(),
             )
         );
index 7dc9c65..3a74afc 100644 (file)
@@ -453,4 +453,94 @@ class core_group_externallib_testcase extends externallib_advanced_testcase {
         $this->assertCount(1, $groups['warnings']);
 
     }
+
+    /**
+     * Test get_activity_allowed_groups
+     */
+    public function test_get_activity_allowed_groups() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $generator = self::getDataGenerator();
+
+        $student = $generator->create_user();
+        $otherstudent = $generator->create_user();
+        $teacher = $generator->create_user();
+        $course = $generator->create_course();
+        $othercourse = $generator->create_course();
+
+        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
+        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
+        $generator->enrol_user($student->id, $course->id, $studentrole->id);
+        $generator->enrol_user($otherstudent->id, $othercourse->id, $studentrole->id);
+        $generator->enrol_user($teacher->id, $course->id, $teacherrole->id);
+
+        $forum1 = $generator->create_module("forum", array('course' => $course->id), array('groupmode' => VISIBLEGROUPS));
+        $forum2 = $generator->create_module("forum", array('course' => $othercourse->id));
+        $forum3 = $generator->create_module("forum", array('course' => $course->id), array('visible' => 0));
+
+        // Request data for tests.
+        $cm1 = get_coursemodule_from_instance("forum", $forum1->id);
+        $cm2 = get_coursemodule_from_instance("forum", $forum2->id);
+        $cm3 = get_coursemodule_from_instance("forum", $forum3->id);
+
+        $group1data = array();
+        $group1data['courseid'] = $course->id;
+        $group1data['name'] = 'Group Test 1';
+        $group1data['description'] = 'Group Test 1 description';
+        $group1data['idnumber'] = 'TEST1';
+        $group2data = array();
+        $group2data['courseid'] = $course->id;
+        $group2data['name'] = 'Group Test 2';
+        $group2data['description'] = 'Group Test 2 description';
+        $group2data['idnumber'] = 'TEST2';
+        $group1 = $generator->create_group($group1data);
+        $group2 = $generator->create_group($group2data);
+
+        groups_add_member($group1->id, $student->id);
+        groups_add_member($group2->id, $student->id);
+
+        $this->setUser($student);
+
+        // First try possible errors.
+        try {
+            $data = core_group_external::get_activity_allowed_groups($cm2->id);
+        } catch (moodle_exception $e) {
+            $this->assertEquals('requireloginerror', $e->errorcode);
+        }
+
+        try {
+            $data = core_group_external::get_activity_allowed_groups($cm3->id);
+        } catch (moodle_exception $e) {
+            $this->assertEquals('requireloginerror', $e->errorcode);
+        }
+
+        // Retrieve my groups.
+        $groups = core_group_external::get_activity_allowed_groups($cm1->id);
+        $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
+        $this->assertCount(2, $groups['groups']);
+
+        foreach ($groups['groups'] as $group) {
+            if ($group['name'] == $group1data['name']) {
+                $this->assertEquals($group1data['description'], $group['description']);
+                $this->assertEquals($group1data['idnumber'], $group['idnumber']);
+            } else {
+                $this->assertEquals($group2data['description'], $group['description']);
+                $this->assertEquals($group2data['idnumber'], $group['idnumber']);
+            }
+        }
+
+        $this->setUser($teacher);
+        // Retrieve other users groups.
+        $groups = core_group_external::get_activity_allowed_groups($cm1->id, $student->id);
+        $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
+        $this->assertCount(2, $groups['groups']);
+
+        // Check warnings. Trying to get groups for a user not enrolled in course.
+        $groups = core_group_external::get_activity_allowed_groups($cm1->id, $otherstudent->id);
+        $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
+        $this->assertCount(1, $groups['warnings']);
+
+    }
 }
index a515848..c9a2703 100644 (file)
@@ -323,6 +323,15 @@ $functions = array(
         'capabilities'  => 'moodle/course:managegroups',
     ),
 
+    'core_group_get_activity_allowed_groups' => array(
+        'classname'     => 'core_group_external',
+        'methodname'    => 'get_activity_allowed_groups',
+        'classpath'     => 'group/externallib.php',
+        'description'   => 'Gets a list of groups that the user is allowed to access within the specified activity.',
+        'type'          => 'read',
+        'capabilities'  => '',
+    ),
+
     'core_notes_get_course_notes' => array(
         'classname'     => 'core_notes_external',
         'methodname'    => 'get_course_notes',
@@ -1147,6 +1156,7 @@ $services = array(
             'core_message_get_blocked_users',
             'gradereport_user_get_grades_table',
             'core_group_get_course_user_groups',
+            'core_group_get_activity_allowed_groups',
             'core_user_remove_user_device',
             'core_course_get_courses',
             'core_completion_update_activity_completion_status_manually',