mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 12:32:08 +02:00
MDL-67752 course: Improve the average_number_of_participants function
The patch adds two new optional parameters that control the function behaviour. With default values, the function is backwards compatible and it simply uses the number of enrolment records. The new parameters allow to include only active enrolments and/or only recently active users.
This commit is contained in:
parent
37b2ee3f64
commit
c268c1bd3f
@ -2612,31 +2612,68 @@ function update_course($data, $editoroptions = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Average number of participants
|
||||
* @return integer
|
||||
* Calculate the average number of enrolled participants per course.
|
||||
*
|
||||
* This is intended for statistics purposes during the site registration. Only visible courses are taken into account.
|
||||
* Front page enrolments are excluded.
|
||||
*
|
||||
* @param bool $onlyactive Consider only active enrolments in enabled plugins and obey the enrolment time restrictions.
|
||||
* @param int $lastloginsince If specified, count only users who logged in after this timestamp.
|
||||
* @return float
|
||||
*/
|
||||
function average_number_of_participants() {
|
||||
global $DB, $SITE;
|
||||
function average_number_of_participants(bool $onlyactive = false, int $lastloginsince = null): float {
|
||||
global $DB;
|
||||
|
||||
$params = [
|
||||
'siteid' => SITEID,
|
||||
];
|
||||
|
||||
$sql = "SELECT DISTINCT ue.userid, e.courseid
|
||||
FROM {user_enrolments} ue
|
||||
JOIN {enrol} e ON e.id = ue.enrolid
|
||||
JOIN {course} c ON c.id = e.courseid ";
|
||||
|
||||
if ($onlyactive || $lastloginsince) {
|
||||
$sql .= "JOIN {user} u ON u.id = ue.userid ";
|
||||
}
|
||||
|
||||
$sql .= "WHERE e.courseid <> :siteid
|
||||
AND c.visible = 1 ";
|
||||
|
||||
if ($onlyactive) {
|
||||
$sql .= "AND ue.status = :active
|
||||
AND e.status = :enabled
|
||||
AND ue.timestart < :now1
|
||||
AND (ue.timeend = 0 OR ue.timeend > :now2) ";
|
||||
|
||||
// Same as in the enrollib - the rounding should help caching in the database.
|
||||
$now = round(time(), -2);
|
||||
|
||||
$params += [
|
||||
'active' => ENROL_USER_ACTIVE,
|
||||
'enabled' => ENROL_INSTANCE_ENABLED,
|
||||
'now1' => $now,
|
||||
'now2' => $now,
|
||||
];
|
||||
}
|
||||
|
||||
if ($lastloginsince) {
|
||||
$sql .= "AND u.lastlogin > :lastlogin ";
|
||||
$params['lastlogin'] = $lastloginsince;
|
||||
}
|
||||
|
||||
$sql = "SELECT COUNT(*)
|
||||
FROM ($sql) total";
|
||||
|
||||
//count total of enrolments for visible course (except front page)
|
||||
$sql = 'SELECT COUNT(*) FROM (
|
||||
SELECT DISTINCT ue.userid, e.courseid
|
||||
FROM {user_enrolments} ue, {enrol} e, {course} c
|
||||
WHERE ue.enrolid = e.id
|
||||
AND e.courseid <> :siteid
|
||||
AND c.id = e.courseid
|
||||
AND c.visible = 1) total';
|
||||
$params = array('siteid' => $SITE->id);
|
||||
$enrolmenttotal = $DB->count_records_sql($sql, $params);
|
||||
|
||||
// Get the number of visible courses (exclude the front page).
|
||||
$coursetotal = $DB->count_records('course', ['visible' => 1]);
|
||||
$coursetotal = $coursetotal - 1;
|
||||
|
||||
//count total of visible courses (minus front page)
|
||||
$coursetotal = $DB->count_records('course', array('visible' => 1));
|
||||
$coursetotal = $coursetotal - 1 ;
|
||||
|
||||
//average of enrolment
|
||||
if (empty($coursetotal)) {
|
||||
$participantaverage = 0;
|
||||
|
||||
} else {
|
||||
$participantaverage = $enrolmenttotal / $coursetotal;
|
||||
}
|
||||
|
@ -6945,4 +6945,78 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||
// Manager has permissions.
|
||||
$this->assertTrue(course_allowed_module($course, 'assign', $manager));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the {@link average_number_of_participants()} function.
|
||||
*/
|
||||
public function test_average_number_of_participants() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
$now = time();
|
||||
|
||||
// If there are no courses, expect zero number of participants per course.
|
||||
$this->assertEquals(0, average_number_of_participants());
|
||||
|
||||
$c1 = $generator->create_course();
|
||||
$c2 = $generator->create_course();
|
||||
|
||||
// If there are no users, expect zero number of participants per course.
|
||||
$this->assertEquals(0, average_number_of_participants());
|
||||
|
||||
$t1 = $generator->create_user(['lastlogin' => $now]);
|
||||
$s1 = $generator->create_user(['lastlogin' => $now]);
|
||||
$s2 = $generator->create_user(['lastlogin' => $now - WEEKSECS]);
|
||||
$s3 = $generator->create_user(['lastlogin' => $now - WEEKSECS]);
|
||||
$s4 = $generator->create_user(['lastlogin' => $now - YEARSECS]);
|
||||
|
||||
// We have courses, we have users, but no enrolments yet.
|
||||
$this->assertEquals(0, average_number_of_participants());
|
||||
|
||||
// Front page enrolments are ignored.
|
||||
$generator->enrol_user($t1->id, SITEID, 'teacher');
|
||||
$this->assertEquals(0, average_number_of_participants());
|
||||
|
||||
// The teacher enrolled into one of the two courses.
|
||||
$generator->enrol_user($t1->id, $c1->id, 'editingteacher');
|
||||
$this->assertEquals(0.5, average_number_of_participants());
|
||||
|
||||
// The teacher enrolled into both courses.
|
||||
$generator->enrol_user($t1->id, $c2->id, 'editingteacher');
|
||||
$this->assertEquals(1, average_number_of_participants());
|
||||
|
||||
// Student 1 enrolled in the Course 1 only.
|
||||
$generator->enrol_user($s1->id, $c1->id, 'student');
|
||||
$this->assertEquals(1.5, average_number_of_participants());
|
||||
|
||||
// Student 2 enrolled in both courses, but the enrolment in the Course 2 not active yet (enrolment starts in the future).
|
||||
$generator->enrol_user($s2->id, $c1->id, 'student');
|
||||
$generator->enrol_user($s2->id, $c2->id, 'student', 'manual', $now + WEEKSECS);
|
||||
$this->assertEquals(2.5, average_number_of_participants());
|
||||
$this->assertEquals(2, average_number_of_participants(true));
|
||||
|
||||
// Student 3 enrolled in the Course 1, but the enrolment already expired.
|
||||
$generator->enrol_user($s3->id, $c1->id, 'student', 'manual', 0, $now - YEARSECS);
|
||||
$this->assertEquals(3, average_number_of_participants());
|
||||
$this->assertEquals(2, average_number_of_participants(true));
|
||||
|
||||
// Student 4 enrolled in both courses, but the enrolment has been suspended.
|
||||
$generator->enrol_user($s4->id, $c1->id, 'student', 'manual', 0, 0, ENROL_USER_SUSPENDED);
|
||||
$generator->enrol_user($s4->id, $c2->id, 'student', 'manual', $now - DAYSECS, $now + YEARSECS, ENROL_USER_SUSPENDED);
|
||||
$this->assertEquals(4, average_number_of_participants());
|
||||
$this->assertEquals(2, average_number_of_participants(true));
|
||||
|
||||
// Consider only t1 and s1 who logged in recently.
|
||||
$this->assertEquals(1.5, average_number_of_participants(false, $now - DAYSECS));
|
||||
|
||||
// Consider only t1, s1, s2 and s3 who logged in in recent weeks.
|
||||
$this->assertEquals(3, average_number_of_participants(false, $now - 4 * WEEKSECS));
|
||||
|
||||
// Hidden courses are excluded from stats.
|
||||
$DB->set_field('course', 'visible', 0, ['id' => $c1->id]);
|
||||
$this->assertEquals(3, average_number_of_participants());
|
||||
$this->assertEquals(1, average_number_of_participants(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user