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];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user