MDL-63062 block_recentlyaccessedcourses: add web service
This commit is contained in:
committed by
Víctor Déniz Falcón
parent
bebef89174
commit
98a52c80bb
Vendored
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/ajax"],function(a,b){var c=function(a,c,d,e){var f={classification:a};"undefined"!=typeof c&&(f.limit=c),"undefined"!=typeof d&&(f.offset=d),"undefined"!=typeof e&&(f.sort=e);var g={methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:f};return b.call([g])[0]};return{getEnrolledCoursesByTimelineClassification:c}});
|
||||
define(["jquery","core/ajax"],function(a,b){var c=function(a,c,d,e){var f={classification:a};"undefined"!=typeof c&&(f.limit=c),"undefined"!=typeof d&&(f.offset=d),"undefined"!=typeof e&&(f.sort=e);var g={methodname:"core_course_get_enrolled_courses_by_timeline_classification",args:f};return b.call([g])[0]},d=function(a,c,d,e){var f={userid:a};"undefined"!=typeof c&&(f.limit=c),"undefined"!=typeof d&&(f.offset=d),"undefined"!=typeof e&&(f.sort=e);var g={methodname:"core_course_get_recent_courses",args:f};return b.call([g])[0]};return{getEnrolledCoursesByTimelineClassification:c,getLastAccessedCourses:d}});
|
||||
@@ -57,7 +57,45 @@ define(['jquery', 'core/ajax'], function($, Ajax) {
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of courses that the user has most recently accessed.
|
||||
*
|
||||
* @method getLastAccessedCourses
|
||||
* @param {int} userid User from which the courses will be obtained
|
||||
* @param {int} limit Only return this many results
|
||||
* @param {int} offset Skip this many results from the start of the result set
|
||||
* @param {string} sort Column to sort by and direction, e.g. 'shortname asc'
|
||||
* @return {promise} Resolved with an array of courses
|
||||
*/
|
||||
var getLastAccessedCourses = function(userid, limit, offset, sort) {
|
||||
var args = {};
|
||||
|
||||
if (typeof userid !== 'undefined') {
|
||||
args.limit = limit;
|
||||
}
|
||||
|
||||
if (typeof limit !== 'undefined') {
|
||||
args.limit = limit;
|
||||
}
|
||||
|
||||
if (typeof offset !== 'undefined') {
|
||||
args.offset = offset;
|
||||
}
|
||||
|
||||
if (typeof sort !== 'undefined') {
|
||||
args.sort = sort;
|
||||
}
|
||||
|
||||
var request = {
|
||||
methodname: 'core_course_get_recent_courses',
|
||||
args: args
|
||||
};
|
||||
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
return {
|
||||
getEnrolledCoursesByTimelineClassification: getEnrolledCoursesByTimelineClassification
|
||||
getEnrolledCoursesByTimelineClassification: getEnrolledCoursesByTimelineClassification,
|
||||
getLastAccessedCourses: getLastAccessedCourses
|
||||
};
|
||||
});
|
||||
|
||||
@@ -141,6 +141,10 @@ class course_summary_exporter extends \core\external\exporter {
|
||||
),
|
||||
'hidden' => array(
|
||||
'type' => PARAM_BOOL
|
||||
),
|
||||
'timeaccess' => array(
|
||||
'type' => PARAM_INT,
|
||||
'optional' => true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ defined('MOODLE_INTERNAL') || die;
|
||||
use core_course\external\course_summary_exporter;
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
require_once("lib.php");
|
||||
|
||||
/**
|
||||
* Course external functions
|
||||
@@ -3886,4 +3887,84 @@ class core_course_external extends external_api {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since Moodle 3.6
|
||||
*/
|
||||
public static function get_recent_courses_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'userid' => new external_value(PARAM_INT, 'id of the user, default to current user', VALUE_DEFAULT, 0),
|
||||
'limit' => new external_value(PARAM_INT, 'result set limit', VALUE_DEFAULT, 0),
|
||||
'offset' => new external_value(PARAM_INT, 'Result set offset', VALUE_DEFAULT, 0),
|
||||
'sort' => new external_value(PARAM_TEXT, 'Sort string', VALUE_DEFAULT, null)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last accessed courses adding additional course information like images.
|
||||
*
|
||||
* @param int $userid User id from which the courses will be obtained
|
||||
* @param int $limit Restrict result set to this amount
|
||||
* @param int $offset Skip this number of records from the start of the result set
|
||||
* @param string|null $sort SQL string for sorting
|
||||
* @return array List of courses
|
||||
* @throws invalid_parameter_exception
|
||||
*/
|
||||
public static function get_recent_courses(int $userid = 0, int $limit = 0, int $offset = 0, string $sort = null) {
|
||||
global $USER, $PAGE;
|
||||
|
||||
if (empty($userid)) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
||||
$params = self::validate_parameters(self::get_recent_courses_parameters(),
|
||||
array(
|
||||
'userid' => $userid,
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'sort' => $sort
|
||||
)
|
||||
);
|
||||
|
||||
$userid = $params['userid'];
|
||||
$limit = $params['limit'];
|
||||
$offset = $params['offset'];
|
||||
$sort = $params['sort'];
|
||||
|
||||
$usercontext = context_user::instance($userid);
|
||||
|
||||
self::validate_context($usercontext);
|
||||
|
||||
if ($userid != $USER->id and !has_capability('moodle/user:viewdetails', $usercontext)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$courses = course_get_recent_courses($userid, $limit, $offset, $sort);
|
||||
|
||||
$renderer = $PAGE->get_renderer('core');
|
||||
|
||||
$recentcourses = array_map(function($course) use ($renderer) {
|
||||
context_helper::preload_from_record($course);
|
||||
$context = context_course::instance($course->id);
|
||||
$exporter = new course_summary_exporter($course, ['context' => $context]);
|
||||
return $exporter->export($renderer);
|
||||
}, $courses);
|
||||
|
||||
return $recentcourses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value
|
||||
*
|
||||
* @return external_description
|
||||
* @since Moodle 3.6
|
||||
*/
|
||||
public static function get_recent_courses_returns() {
|
||||
return new external_multiple_structure(course_summary_exporter::get_read_structure(), 'Courses');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4529,3 +4529,69 @@ function get_hidden_courses_on_timeline($user = null) {
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the most recently courses accessed by a user
|
||||
*
|
||||
* @param int $userid User id from which the courses will be obtained
|
||||
* @param int $limit Restrict result set to this amount
|
||||
* @param int $offset Skip this number of records from the start of the result set
|
||||
* @param string|null $sort SQL string for sorting
|
||||
* @return array
|
||||
*/
|
||||
function course_get_recent_courses(int $userid = null, int $limit = 0, int $offset = 0, string $sort = null) {
|
||||
|
||||
global $CFG, $USER, $DB;
|
||||
|
||||
if (empty($userid)) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
||||
$basefields = array('id', 'idnumber', 'summary', 'summaryformat', 'startdate', 'enddate', 'category',
|
||||
'shortname', 'fullname', 'userid', 'timeaccess');
|
||||
|
||||
$sort = trim($sort);
|
||||
if (empty($sort)) {
|
||||
$sort = 'timeaccess DESC';
|
||||
} else {
|
||||
$rawsorts = explode(',', $sort);
|
||||
$sorts = array();
|
||||
foreach ($rawsorts as $rawsort) {
|
||||
$rawsort = trim($rawsort);
|
||||
$sorts[] = trim($rawsort);
|
||||
}
|
||||
$sort = implode(',', $sorts);
|
||||
}
|
||||
|
||||
$orderby = "ORDER BY $sort";
|
||||
|
||||
$ctxfields = context_helper::get_preload_record_columns_sql('ctx');
|
||||
|
||||
$coursefields = 'c.' .join(',', $basefields);
|
||||
|
||||
$sql = "SELECT $ctxfields, $coursefields
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON ctx.contextlevel = :contextlevel
|
||||
AND ctx.instanceid = c.id
|
||||
JOIN {user_lastaccess} ul ON ul.courseid = c.id
|
||||
WHERE ul.userid = :userid
|
||||
$orderby";
|
||||
$params = ['userid' => $userid, 'contextlevel' => CONTEXT_COURSE];
|
||||
|
||||
$recentcourses = $DB->get_records_sql($sql, $params, $offset, $limit);
|
||||
|
||||
// Filter courses if last access field is hidden.
|
||||
$hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
|
||||
|
||||
if ($userid != $USER->id && isset($hiddenfields['lastaccess'])) {
|
||||
$recentcourses = array_filter($recentcourses, function($course) {
|
||||
context_helper::preload_from_record($course);
|
||||
$context = context_course::instance($course->id, IGNORE_MISSING);
|
||||
// If last access was a hidden field, a user requesting info about another user would need permission to view hidden
|
||||
// fields.
|
||||
return has_capability('moodle/course:viewhiddenuserfields', $context);
|
||||
});
|
||||
}
|
||||
|
||||
return $recentcourses;
|
||||
}
|
||||
|
||||
@@ -2744,4 +2744,86 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($expectedcourses, $actual);
|
||||
$this->assertEquals($expectednextoffset, $result['nextoffset']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_recent_courses function.
|
||||
*/
|
||||
public function test_get_recent_courses() {
|
||||
global $USER, $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
set_config('hiddenuserfields', 'lastaccess');
|
||||
|
||||
$courses = array();
|
||||
for ($i = 1; $i < 12; $i++) {
|
||||
$courses[] = $generator->create_course();
|
||||
};
|
||||
|
||||
$student = $generator->create_user();
|
||||
$teacher = $generator->create_user();
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$generator->enrol_user($student->id, $course->id, 'student');
|
||||
}
|
||||
|
||||
$generator->enrol_user($teacher->id, $courses[0]->id, 'teacher');
|
||||
|
||||
$this->setUser($student);
|
||||
|
||||
$result = core_course_external::get_recent_courses($USER->id);
|
||||
|
||||
// No course accessed.
|
||||
$this->assertCount(0, $result);
|
||||
|
||||
foreach ($courses as $course) {
|
||||
core_course_external::view_course($course->id);
|
||||
}
|
||||
|
||||
// Every course accessed.
|
||||
$result = core_course_external::get_recent_courses($USER->id);
|
||||
$this->assertCount( 11, $result);
|
||||
|
||||
// Every course accessed, result limited to 10 courses.
|
||||
$result = core_course_external::get_recent_courses($USER->id, 10);
|
||||
$this->assertCount(10, $result);
|
||||
|
||||
$guestcourse = $generator->create_course(
|
||||
(object)array('shortname' => 'guestcourse',
|
||||
'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
|
||||
'enrol_guest_password_0' => ''));
|
||||
core_course_external::view_course($guestcourse->id);
|
||||
|
||||
// Every course accessed, even the not enrolled one.
|
||||
$result = core_course_external::get_recent_courses($USER->id);
|
||||
$this->assertCount(12, $result);
|
||||
|
||||
// Offset 5, return 7 out of 12.
|
||||
$result = core_course_external::get_recent_courses($USER->id, 0, 5);
|
||||
$this->assertCount(7, $result);
|
||||
|
||||
// Offset 5 and limit 3, return 3 out of 12.
|
||||
$result = core_course_external::get_recent_courses($USER->id, 3, 5);
|
||||
$this->assertCount(3, $result);
|
||||
|
||||
// Sorted by course id ASC.
|
||||
$result = core_course_external::get_recent_courses($USER->id, 0, 0, 'id ASC');
|
||||
$this->assertEquals($courses[0]->id, array_shift($result)->id);
|
||||
|
||||
// Sorted by course id DESC.
|
||||
$result = core_course_external::get_recent_courses($USER->id, 0, 0, 'id DESC');
|
||||
$this->assertEquals($guestcourse->id, array_shift($result)->id);
|
||||
|
||||
// If last access is hidden, only get the courses where has viewhiddenuserfields capability.
|
||||
$this->setUser($teacher);
|
||||
$teacherroleid = $DB->get_field('role', 'id', array('shortname' => 'editingteacher'));
|
||||
$usercontext = context_user::instance($student->id);
|
||||
$this->assignUserCapability('moodle/user:viewdetails', $usercontext, $teacherroleid);
|
||||
|
||||
// Sorted by course id DESC.
|
||||
$result = core_course_external::get_recent_courses($student->id);
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals($courses[0]->id, array_shift($result)->id);
|
||||
}
|
||||
}
|
||||
@@ -544,6 +544,14 @@ $functions = array(
|
||||
'type' => 'read',
|
||||
'ajax' => true
|
||||
),
|
||||
'core_course_get_recent_courses' => array(
|
||||
'classname' => 'core_course_external',
|
||||
'methodname' => 'get_recent_courses',
|
||||
'classpath' => 'course/externallib.php',
|
||||
'description' => 'List of courses a user has accessed most recently.',
|
||||
'type' => 'read',
|
||||
'ajax' => true
|
||||
),
|
||||
'core_enrol_get_course_enrolment_methods' => array(
|
||||
'classname' => 'core_enrol_external',
|
||||
'methodname' => 'get_course_enrolment_methods',
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2018110300.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2018110300.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user