MDL-66144 course: add function to calculate user course dates
This commit is contained in:
+151
@@ -4666,3 +4666,154 @@ function course_get_recent_courses(int $userid = null, int $limit = 0, int $offs
|
||||
|
||||
return $recentcourses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the course start date and offset for the given user ids.
|
||||
*
|
||||
* If the course is a fixed date course then the course start date will be returned.
|
||||
* If the course is a relative date course then the course date will be calculated and
|
||||
* and offset provided.
|
||||
*
|
||||
* The dates are returned as an array with the index being the user id. The array
|
||||
* contains the start date and start offset values for the user.
|
||||
*
|
||||
* If the user is not enrolled in the course then the course start date will be returned.
|
||||
*
|
||||
* If we have a course which starts on 1563244000 and 2 users, id 123 and 456, where the
|
||||
* former is enrolled in the course at 1563244693 and the latter is not enrolled then the
|
||||
* return value would look like:
|
||||
* [
|
||||
* '123' => [
|
||||
* 'start' => 1563244693,
|
||||
* 'startoffset' => 693
|
||||
* ],
|
||||
* '456' => [
|
||||
* 'start' => 1563244000,
|
||||
* 'startoffset' => 0
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* @param stdClass $course The course to fetch dates for.
|
||||
* @param array $userids The list of user ids to get dates for.
|
||||
* @return array
|
||||
*/
|
||||
function course_get_course_dates_for_user_ids(stdClass $course, array $userids): array {
|
||||
if (empty($course->relativedatesmode)) {
|
||||
// This course isn't set to relative dates so we can early return with the course
|
||||
// start date.
|
||||
return array_reduce($userids, function($carry, $userid) use ($course) {
|
||||
$carry[$userid] = [
|
||||
'start' => $course->startdate,
|
||||
'startoffset' => 0
|
||||
];
|
||||
return $carry;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// We're dealing with a relative dates course now so we need to calculate some dates.
|
||||
$cache = cache::make('core', 'course_user_dates');
|
||||
$dates = [];
|
||||
$uncacheduserids = [];
|
||||
|
||||
// Try fetching the values from the cache so that we don't need to do a DB request.
|
||||
foreach ($userids as $userid) {
|
||||
$cachekey = "{$course->id}_{$userid}";
|
||||
$cachedvalue = $cache->get($cachekey);
|
||||
|
||||
if ($cachedvalue === false) {
|
||||
// Looks like we haven't seen this user for this course before so we'll have
|
||||
// to fetch it.
|
||||
$uncacheduserids[] = $userid;
|
||||
} else {
|
||||
[$start, $startoffset] = $cachedvalue;
|
||||
$dates[$userid] = [
|
||||
'start' => $start,
|
||||
'startoffset' => $startoffset
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($uncacheduserids)) {
|
||||
// Load the enrolments for any users we haven't seen yet. Set the "onlyactive" param
|
||||
// to false because it filters out users with enrolment start times in the future which
|
||||
// we don't want.
|
||||
$enrolments = enrol_get_course_users($course->id, false, $uncacheduserids);
|
||||
|
||||
foreach ($uncacheduserids as $userid) {
|
||||
// Find the user enrolment that has the earliest start date.
|
||||
$enrolment = array_reduce(array_values($enrolments), function($carry, $enrolment) use ($userid) {
|
||||
// Only consider enrolments for this user if the user enrolment is active and the
|
||||
// enrolment method is enabled.
|
||||
if (
|
||||
$enrolment->uestatus == ENROL_USER_ACTIVE &&
|
||||
$enrolment->estatus == ENROL_INSTANCE_ENABLED &&
|
||||
$enrolment->id == $userid
|
||||
) {
|
||||
if (is_null($carry)) {
|
||||
// Haven't found an enrolment yet for this user so use the one we just found.
|
||||
$carry = $enrolment;
|
||||
} else {
|
||||
// We've already found an enrolment for this user so let's use which ever one
|
||||
// has the earliest start time.
|
||||
$carry = $carry->uetimestart < $enrolment->uetimestart ? $carry : $enrolment;
|
||||
}
|
||||
}
|
||||
|
||||
return $carry;
|
||||
}, null);
|
||||
|
||||
if ($enrolment) {
|
||||
// The course is in relative dates mode so we calculate the student's start
|
||||
// date based on their enrolment start date.
|
||||
$start = $course->startdate > $enrolment->uetimestart ? $course->startdate : $enrolment->uetimestart;
|
||||
$startoffset = $start - $course->startdate;
|
||||
} else {
|
||||
// The user is not enrolled in the course so default back to the course start date.
|
||||
$start = $course->startdate;
|
||||
$startoffset = 0;
|
||||
}
|
||||
|
||||
$dates[$userid] = [
|
||||
'start' => $start,
|
||||
'startoffset' => $startoffset
|
||||
];
|
||||
|
||||
$cachekey = "{$course->id}_{$userid}";
|
||||
$cache->set($cachekey, [$start, $startoffset]);
|
||||
}
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the course start date and offset for the given user id.
|
||||
*
|
||||
* If the course is a fixed date course then the course start date will be returned.
|
||||
* If the course is a relative date course then the course date will be calculated and
|
||||
* and offset provided.
|
||||
*
|
||||
* The return array contains the start date and start offset values for the user.
|
||||
*
|
||||
* If the user is not enrolled in the course then the course start date will be returned.
|
||||
*
|
||||
* If we have a course which starts on 1563244000. If a user's enrolment starts on 1563244693
|
||||
* then the return would be:
|
||||
* [
|
||||
* 'start' => 1563244693,
|
||||
* 'startoffset' => 693
|
||||
* ]
|
||||
*
|
||||
* If the use was not enrolled then the return would be:
|
||||
* [
|
||||
* 'start' => 1563244000,
|
||||
* 'startoffset' => 0
|
||||
* ]
|
||||
*
|
||||
* @param stdClass $course The course to fetch dates for.
|
||||
* @param int $userid The user id to get dates for.
|
||||
* @return array
|
||||
*/
|
||||
function course_get_course_dates_for_user_id(stdClass $course, int $userid): array {
|
||||
return (course_get_course_dates_for_user_ids($course, [$userid]))[$userid];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,7 @@ $string['cachedef_coursecattree'] = 'Course categories tree';
|
||||
$string['cachedef_coursecompletion'] = 'Course completion status';
|
||||
$string['cachedef_coursecontacts'] = 'List of course contacts';
|
||||
$string['cachedef_coursemodinfo'] = 'Accumulated information about modules and sections for each course';
|
||||
$string['cachedef_course_user_dates'] = 'The user dates for courses set to relative dates mode';
|
||||
$string['cachedef_completion'] = 'Activity completion status';
|
||||
$string['cachedef_databasemeta'] = 'Database meta information';
|
||||
$string['cachedef_eventinvalidation'] = 'Event invalidation';
|
||||
|
||||
@@ -400,4 +400,12 @@ $definitions = array(
|
||||
'simplekeys' => true,
|
||||
'staticacceleration' => true
|
||||
],
|
||||
|
||||
// Cache the user dates for courses set to relative dates mode.
|
||||
'course_user_dates' => [
|
||||
'mode' => cache_store::MODE_REQUEST,
|
||||
'simplekeys' => true,
|
||||
'simpledata' => true,
|
||||
'staticacceleration' => true
|
||||
],
|
||||
);
|
||||
|
||||
+1
-1
@@ -1664,7 +1664,7 @@ function enrol_get_course_users($courseid = false, $onlyactive = false, $usersfi
|
||||
|
||||
$sql = "SELECT ue.id AS ueid, ue.status AS uestatus, ue.enrolid AS ueenrolid, ue.timestart AS uetimestart,
|
||||
ue.timeend AS uetimeend, ue.modifierid AS uemodifierid, ue.timecreated AS uetimecreated,
|
||||
ue.timemodified AS uetimemodified,
|
||||
ue.timemodified AS uetimemodified, e.status AS estatus,
|
||||
u.* FROM {user_enrolments} ue
|
||||
JOIN {enrol} e ON e.id = ue.enrolid
|
||||
JOIN {user} u ON ue.userid = u.id
|
||||
|
||||
Reference in New Issue
Block a user