diff --git a/mod/assign/externallib.php b/mod/assign/externallib.php index 5c7d8624040..ef7d0166a17 100644 --- a/mod/assign/externallib.php +++ b/mod/assign/externallib.php @@ -245,7 +245,7 @@ class mod_assign_external extends external_api { return new external_function_parameters( array( 'courseids' => new external_multiple_structure( - new external_value(PARAM_INT, 'course id'), + new external_value(PARAM_INT, 'course id, empty for retrieving all the courses where the user is enroled in'), '0 or more course ids', VALUE_DEFAULT, array() ), @@ -253,37 +253,57 @@ class mod_assign_external extends external_api { new external_value(PARAM_CAPABILITY, 'capability'), 'list of capabilities used to filter courses', VALUE_DEFAULT, array() - ) + ), + 'includenotenrolledcourses' => new external_value(PARAM_BOOL, 'whether to return courses that the user can see + even if is not enroled in. This requires the parameter courseids + to not be empty.', VALUE_DEFAULT, false) ) ); } /** - * Returns an array of courses the user is enrolled in, and for each course all of the assignments that the user can + * Returns an array of courses the user is enrolled, and for each course all of the assignments that the user can * view within that course. * * @param array $courseids An optional array of course ids. If provided only assignments within the given course - * will be returned. If the user is not enrolled in a given course a warning will be generated and returned. + * will be returned. If the user is not enrolled in or can't view a given course a warning will be generated and returned. * @param array $capabilities An array of additional capability checks you wish to be made on the course context. + * @param bool $includenotenrolledcourses Wheter to return courses that the user can see even if is not enroled in. + * This requires the parameter $courseids to not be empty. * @return An array of courses and warnings. * @since Moodle 2.4 */ - public static function get_assignments($courseids = array(), $capabilities = array()) { + public static function get_assignments($courseids = array(), $capabilities = array(), $includenotenrolledcourses = false) { global $USER, $DB, $CFG; require_once("$CFG->dirroot/mod/assign/locallib.php"); $params = self::validate_parameters( self::get_assignments_parameters(), - array('courseids' => $courseids, 'capabilities' => $capabilities) + array( + 'courseids' => $courseids, + 'capabilities' => $capabilities, + 'includenotenrolledcourses' => $includenotenrolledcourses + ) ); $warnings = array(); + $courses = array(); $fields = 'sortorder,shortname,fullname,timemodified'; - $courses = enrol_get_users_courses($USER->id, true, $fields); - // Used to test for ids that have been requested but can't be returned. - if (count($params['courseids']) > 0) { + + // If the courseids list is empty, we return only the courses where the user is enrolled in. + if (empty($params['courseids'])) { + $courses = enrol_get_users_courses($USER->id, true, $fields); + $courseids = array_keys($courses); + } else if ($includenotenrolledcourses) { + // In this case, we don't have to check here for enrolmnents. Maybe the user can see the course even if is not enrolled. + $courseids = $params['courseids']; + } else { + // We need to check for enrolments. + $mycourses = enrol_get_users_courses($USER->id, true, $fields); + $mycourseids = array_keys($mycourses); + foreach ($params['courseids'] as $courseid) { - if (!in_array($courseid, array_keys($courses))) { + if (!in_array($courseid, $mycourseids)) { unset($courses[$courseid]); $warnings[] = array( 'item' => 'course', @@ -291,28 +311,35 @@ class mod_assign_external extends external_api { 'warningcode' => '2', 'message' => 'User is not enrolled or does not have requested capability' ); + } else { + $courses[$courseid] = $mycourses[$courseid]; } } + $courseids = array_keys($courses); } - foreach ($courses as $id => $course) { - if (count($params['courseids']) > 0 && !in_array($id, $params['courseids'])) { - unset($courses[$id]); - } - $context = context_course::instance($id); + + foreach ($courseids as $cid) { + try { + $context = context_course::instance($cid); self::validate_context($context); + + // Check if this course was already loaded (by enrol_get_users_courses). + if (!isset($courses[$cid])) { + $courses[$cid] = get_course($cid); + } } catch (Exception $e) { - unset($courses[$id]); + unset($courses[$cid]); $warnings[] = array( 'item' => 'course', - 'itemid' => $id, + 'itemid' => $cid, 'warningcode' => '1', - 'message' => 'No access rights in course context '.$e->getMessage().$e->getTraceAsString() + 'message' => 'No access rights in course context '.$e->getMessage() ); continue; } if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) { - unset($courses[$id]); + unset($courses[$cid]); } } $extrafields='m.id as assignmentid, ' . diff --git a/mod/assign/tests/externallib_test.php b/mod/assign/tests/externallib_test.php index 63e9c36ffbd..a6c2c3c10ca 100644 --- a/mod/assign/tests/externallib_test.php +++ b/mod/assign/tests/externallib_test.php @@ -254,6 +254,35 @@ class mod_assign_external_testcase extends externallib_advanced_testcase { $this->assertEquals(0, count($result['courses'])); $this->assertEquals(1, count($result['warnings'])); + + // Test with non-enrolled user, but with view capabilities. + $this->setAdminUser(); + $result = mod_assign_external::get_assignments(); + $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); + $this->assertEquals(0, count($result['courses'])); + $this->assertEquals(0, count($result['warnings'])); + + // Expect no courses, because we are not using the special flag. + $result = mod_assign_external::get_assignments(array($course1->id)); + $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); + $this->assertCount(0, $result['courses']); + + // Now use the special flag to return courses where you are not enroled in. + $result = mod_assign_external::get_assignments(array($course1->id), array(), true); + $result = external_api::clean_returnvalue(mod_assign_external::get_assignments_returns(), $result); + $this->assertCount(1, $result['courses']); + + $course = $result['courses'][0]; + $this->assertEquals('Lightwork Course 1', $course['fullname']); + $this->assertEquals(1, count($course['assignments'])); + $assignment = $course['assignments'][0]; + $this->assertEquals($assign1->id, $assignment['id']); + $this->assertEquals($course1->id, $assignment['course']); + $this->assertEquals('lightwork assignment', $assignment['name']); + $this->assertArrayNotHasKey('intro', $assignment); + $this->assertArrayNotHasKey('introattachments', $assignment); + $this->assertEquals(1, $assignment['markingworkflow']); + $this->assertEquals(1, $assignment['markingallocation']); } /** diff --git a/mod/assign/upgrade.txt b/mod/assign/upgrade.txt index e6c46528023..c445ad42fcf 100644 --- a/mod/assign/upgrade.txt +++ b/mod/assign/upgrade.txt @@ -8,6 +8,8 @@ This files describes API changes in the assign code. === 3.0 === * assign_submission_status renderable now requires $usergroups in its constructor +* External function mod_assign_external::get_assignments now have a new optional parameter: includenotenrolledcourses. + Its default value is false, setting it to true will return assignments for courses a user can see even if it's not enroled. === 2.9 === * External parameter now returns PARAM_RAW instead of PARAM_TEXT for webservices using feedback comments.