MDL-83896 mod_lesson: Add new methods to lesson class

Add new methods to the lesson class that will be needed by
the overview page.
This commit is contained in:
Mikel Martín
2025-07-03 15:05:21 +02:00
parent d8dbfe4dfd
commit 15f8c92d9e
3 changed files with 167 additions and 1 deletions
@@ -0,0 +1,7 @@
issueNumber: MDL-83896
notes:
mod_lesson:
- message: >-
Added new 'count_all_submissions', 'count_submitted_participants' and
'count_all_participants' functions needed by the overview page.
type: improved
+59 -1
View File
@@ -1963,7 +1963,6 @@ class lesson extends lesson_base {
return $DB->get_records('lesson_attempts', $params, 'timeseen ASC');
}
/**
* Get a list of content pages (formerly known as branch tables) viewed in the lesson for the given user during an attempt.
*
@@ -3034,6 +3033,65 @@ class lesson extends lesson_base {
return $DB->count_records('lesson_grades', array("lessonid" => $this->properties->id, "userid" => $userid));
}
/**
* Count all submissions by all users in the lesson.
*
* @return int the number of submissions (grades table) by all users in the lesson
*/
public function count_all_submissions(): int {
$db = \core\di::get(\moodle_database::class);
[$esql, $eparams] = get_enrolled_sql($this->get_context(), 'mod/lesson:view');
$sql = "SELECT COUNT(lg.id)
FROM {lesson_grades} lg
JOIN ($esql) e ON e.id = lg.userid
WHERE lg.lessonid = :lessonid";
return $db->count_records_sql($sql, ["lessonid" => $this->properties->id] + $eparams);
}
/**
* Count the number of participants that have attempted the lesson.
*
* @return int the number of users that have attempted the lesson
*/
public function count_submitted_participants(): int {
$db = \core\di::get(\moodle_database::class);
[$esql, $eparams] = get_enrolled_sql($this->get_context(), 'mod/lesson:view');
$sql = "SELECT COUNT(DISTINCT lg.userid)
FROM {lesson_grades} lg
JOIN ($esql) e ON e.id = lg.userid
WHERE lg.lessonid = :lessonid";
return $db->count_records_sql($sql, ["lessonid" => $this->properties->id] + $eparams);
}
/**
* Count the number of participants that have access to the lesson.
*
* @return int the number of users that have access to view the lesson
*/
public function count_all_participants(): int {
$db = \core\di::get(\moodle_database::class);
$join = get_enrolled_with_capabilities_join($this->get_context(), '', 'mod/lesson:view');
$managersjoin = get_with_capability_join($this->get_context(), 'mod/lesson:manage', 'u.id');
if (!$managersjoin->cannotmatchanyrows) {
$join = new \core\dml\sql_join(
$join->joins . "\n LEFT " . str_replace('ra', 'manager', $managersjoin->joins),
$join->wheres . " AND manager.userid IS NULL",
$join->params
);
}
$sql = "SELECT COUNT(DISTINCT u.id)
FROM {user} u
$join->joins
WHERE $join->wheres";
return $db->count_records_sql($sql, $join->params);
}
/**
* Check if a user left a timed session.
*
+101
View File
@@ -25,6 +25,7 @@
namespace mod_lesson;
use lesson;
use core\context\module as context_module;
defined('MOODLE_INTERNAL') || die();
@@ -286,4 +287,104 @@ final class locallib_test extends \advanced_testcase {
$lesson = new lesson($lesson);
$this->assertEquals($expected, $lesson->get_last_attempt($attempts));
}
/**
* Helper function to create attempts for a lesson.
*
* @param lesson $lesson The lesson object.
* @param int $userid The user ID for whom the attempts are created.
* @param int $count The number of attempts to create.
*/
private function create_user_submissions(lesson $lesson, int $userid, int $count): void {
/** @var \mod_lesson_generator $lessongenerator */
$lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
for ($i = 0; $i < $count; $i++) {
$lessongenerator->create_submission([
'lessonid' => $lesson->id,
'userid' => $userid,
'grade' => 100,
]);
}
}
/**
* Helper function to create lesson pages with multichoice questions.
*
* @param lesson $lesson The lesson object.
* @param int $count The number of multichoice questions to create.
*/
private function create_lesson_pages(lesson $lesson, int $count): void {
/** @var \mod_lesson_generator $lessongenerator */
$lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
for ($i = 0; $i < $count; $i++) {
$lessongenerator->create_page([
'title' => 'Multichoice question' . ($i + 1),
'content' => 'Question content',
'qtype' => 'multichoice',
'lessonid' => $lesson->id,
]);
$lessongenerator->create_answer(['page' => 'Multichoice question' . ($i + 1), 'answer' => 'A', 'score' => 1]);
$lessongenerator->create_answer(['page' => 'Multichoice question' . ($i + 1), 'answer' => 'B']);
}
$lessongenerator->finish_generate_answer();
}
/**
* Test the count_all_attempts, count_attempted_participants and count_all_participants methods.
*
* @covers \lesson::count_all_submissions
* @covers \lesson::count_submitted_participants
* @covers \lesson::count_all_participants
*/
public function test_count_attempts_and_participants(): void {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$student3 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$student4 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
$lessonrecord = $this->getDataGenerator()->create_module(
'lesson',
['course' => $course, 'retake' => 1]
);
$lesson = new lesson($lessonrecord);
$this->create_lesson_pages($lesson, 2);
$this->create_user_submissions($lesson, $student1->id, 1);
$this->create_user_submissions($lesson, $student2->id, 2);
$this->create_user_submissions($lesson, $student3->id, 2);
$this->setUser($teacher->id);
$this->assertEquals(5, $lesson->count_all_submissions());
$this->assertEquals(3, $lesson->count_submitted_participants());
$this->assertEquals(4, $lesson->count_all_participants());
// Check that the lesson is not counting teachers as participants.
$teacher2 = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
$this->assertEquals(4, $lesson->count_all_participants());
$student5 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$this->assertEquals(5, $lesson->count_all_participants());
// Prohibit mod/lesson:view capability on student role to ensure it does not count students as participants/submissions.
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
assign_capability(
'mod/lesson:view',
CAP_PROHIBIT,
$studentrole->id,
context_module::instance($lesson->get_cm()->id)
);
$this->assertEquals(0, $lesson->count_all_submissions());
$this->assertEquals(0, $lesson->count_submitted_participants());
$this->assertEquals(0, $lesson->count_all_participants());
}
}