diff --git a/mod/bigbluebuttonbn/classes/completion/custom_completion.php b/mod/bigbluebuttonbn/classes/completion/custom_completion.php index 6d141ba0eb8..6d84a1f6687 100644 --- a/mod/bigbluebuttonbn/classes/completion/custom_completion.php +++ b/mod/bigbluebuttonbn/classes/completion/custom_completion.php @@ -48,8 +48,7 @@ class custom_completion extends activity_custom_completion { // Default return value. $value = COMPLETION_INCOMPLETE; - $filters = $rule != "completionview" ? [logger::EVENT_SUMMARY] : [logger::EVENT_JOIN, logger::EVENT_PLAYED]; - $logs = logger::get_user_completion_logs($instance, $this->userid, $filters); + $logs = logger::get_user_completion_logs($instance, $this->userid, [logger::EVENT_SUMMARY]); if (method_exists($this, "get_{$rule}_value")) { $valuecount = $this->count_actions($logs, self::class . "::get_{$rule}_value"); @@ -101,8 +100,6 @@ class custom_completion extends activity_custom_completion { 'completionengagementraisehand', 'completionengagementpollvotes', 'completionengagementemojis', - 'completionview' // Completion view is now a customrule as it depends on the logs and not - // the view action itself. ]; } @@ -141,7 +138,6 @@ class custom_completion extends activity_custom_completion { */ public function get_sort_order(): array { return [ - 'completionview', 'completionengagementchats', 'completionengagementtalks', 'completionengagementraisehand', @@ -166,8 +162,7 @@ class custom_completion extends activity_custom_completion { } $summary = ""; - $filters = $rule != "completionview" ? [logger::EVENT_SUMMARY] : [logger::EVENT_JOIN, logger::EVENT_PLAYED]; - $logs = logger::get_user_completion_logs($instance, $this->userid, $filters); + $logs = logger::get_user_completion_logs($instance, $this->userid, [logger::EVENT_SUMMARY]); if (method_exists($this, "get_{$rule}_value")) { $summary = get_string( @@ -196,29 +191,6 @@ class custom_completion extends activity_custom_completion { return logger::get_user_completion_logs_max_timestamp($instance, $this->userid, $filters); } - /** - * Fetches the list of custom completion rules that are being used by this activity module instance. - * - * @return array - */ - public function get_available_custom_rules(): array { - $availablerules = parent::get_available_custom_rules(); - $availablerules[] = 'completionview'; // Completion view is now a customrule. - return $availablerules; - } - - /** - * Get completion view value - * - * This will override the usual completion value (see COMPLETION_CUSTOM_MODULE_FLOW) - * - * @param stdClass $log - * @return int - */ - protected static function get_completionview_value(stdClass $log): int { - return $log->log == logger::EVENT_PLAYED || $log->log == logger::EVENT_JOIN; - } - /** * Get attendance summary value * diff --git a/mod/bigbluebuttonbn/classes/local/helpers/user_info.php b/mod/bigbluebuttonbn/classes/local/helpers/user_info.php new file mode 100644 index 00000000000..f6a77a4c938 --- /dev/null +++ b/mod/bigbluebuttonbn/classes/local/helpers/user_info.php @@ -0,0 +1,73 @@ +. +namespace mod_bigbluebuttonbn\local\helpers; + +use cm_info; +use mod_bigbluebuttonbn\instance; +use mod_bigbluebuttonbn\logger; +use stdClass; + +/** + * Utility class for all user information + * + * Used mainly in user_outline and user_complete + * + * @package mod_bigbluebuttonbn + * @copyright 2022 onwards, Blindside Networks Inc + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Laurent David (laurent [at] call-learning [dt] fr) + */ +class user_info { + /** + * Event to watch for. + */ + const EVENT_TO_WATCH = [ + 'join' => logger::EVENT_JOIN, + 'play_recording' => logger::EVENT_PLAYED + ]; + + /** + * Get user outline and complete info + * + * @param stdClass $course + * @param stdClass $user + * @param cm_info $mod + * @return array[] an array of infos and timestamps (latest timestamp) + */ + public static function get_user_info_outline(stdClass $course, stdClass $user, cm_info $mod): array { + $completion = new \completion_info($course); + $cdata = $completion->get_data($mod, false, $user->id); + $logtimestamps = []; + $infos = []; + if (!empty($cdata->viewed) && $cdata->viewed) { + $infos[] = get_string('report_room_view', 'mod_bigbluebuttonbn'); + $logtimestamps[] = $cdata->timemodified; + } + $instance = instance::get_from_cmid($mod->id); + foreach (self::EVENT_TO_WATCH as $eventtype => $logtype) { + $logs = logger::get_user_completion_logs($instance, $user->id, [$logtype]); + if ($logs) { + $infos[] = get_string("report_{$eventtype}_info", 'mod_bigbluebuttonbn', count($logs)); + $latesttime = array_reduce($logs, + function($acc, $log) { + return ($acc > $log->timecreated) ? $acc : $log->timecreated; + }, 0); + $logtimestamps[] = $latesttime; + } + } + return [$infos, $logtimestamps]; + } +} diff --git a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php index 2d224634c25..dc033f09805 100644 --- a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php +++ b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php @@ -123,8 +123,8 @@ $string['completionvalidatestate'] = 'Validate completion'; $string['completionvalidatestatetriggered'] = 'Validate completion has been triggered.'; $string['completionview'] = 'Require view'; -$string['completionview_desc'] = 'Student must join a room or play a recording to complete it.'; -$string['completionview_event_desc'] = 'Has joined the room or played a recording {$a} time(s)'; +$string['completionview_desc'] = 'Student must view the Room to complete it.'; +$string['completionview_event_desc'] = 'Has viewed the Room page.'; $string['sendnotification'] = 'Send notification'; $string['minute'] = 'minute'; @@ -378,8 +378,9 @@ $string['mod_form_field_disablenote'] = 'Disable shared notes'; $string['mod_form_field_hideuserlist'] = 'Hide user list'; $string['mod_form_field_lockonjoin'] = 'Lock settings on join'; $string['mod_form_locksettings'] = 'Lock settings'; - - +$string['report_join_info'] = 'Has joined the room {$a} time(s)'; +$string['report_play_recording_info'] = 'Has played a recording {$a} time(s)'; +$string['report_room_view'] = 'Has viewed the Room page'; $string['starts_at'] = 'Starts'; $string['started_at'] = 'Started'; $string['ends_at'] = 'Ends'; diff --git a/mod/bigbluebuttonbn/lib.php b/mod/bigbluebuttonbn/lib.php index db8b31c5f73..93394deec05 100644 --- a/mod/bigbluebuttonbn/lib.php +++ b/mod/bigbluebuttonbn/lib.php @@ -211,24 +211,11 @@ function bigbluebuttonbn_delete_instance($id) { * @return stdClass with info and time (timestamp of the last log) */ function bigbluebuttonbn_user_outline(stdClass $course, stdClass $user, cm_info $mod, stdClass $bigbluebuttonbn): stdClass { - $customcompletion = new custom_completion($mod, $user->id); - $completed = $customcompletion->get_overall_completion_state(); - $result = new stdClass(); - if ($completed) { - $results = []; - $lastlog = 0; - foreach ($customcompletion->get_available_custom_rules() as $rule) { - $results[] = $customcompletion->get_printable_state($rule); - $lastlogrule = $customcompletion->get_last_log_timestamp($rule); - if ($lastlogrule > $lastlog) { - $lastlog = $lastlogrule; - } - } - $result = new stdClass(); - $result->info = join(', ', $results); - $result->time = $lastlog; - } - return $result; + [$infos, $logtimestamps] = \mod_bigbluebuttonbn\local\helpers\user_info::get_user_info_outline($course, $user, $mod); + return (object) [ + 'info' => join(',', $infos), + 'time' => !empty($logtimestamps) ? max($logtimestamps) : 0 + ]; } /** @@ -242,12 +229,8 @@ function bigbluebuttonbn_user_outline(stdClass $course, stdClass $user, cm_info * */ function bigbluebuttonbn_user_complete(stdClass $course, stdClass $user, cm_info $mod, stdClass $bigbluebuttonbn) { - $customcompletion = new custom_completion($mod, $user->id); - $result = []; - foreach ($customcompletion->get_available_custom_rules() as $rule) { - $result[] = $customcompletion->get_printable_state($rule); - } - echo join(', ', $result); + [$infos] = \mod_bigbluebuttonbn\local\helpers\user_info::get_user_info_outline($course, $user, $mod); + echo join(', ', $infos); } /** diff --git a/mod/bigbluebuttonbn/tests/completion_test.php b/mod/bigbluebuttonbn/tests/completion_test.php index 68d66ed9b7f..7083a5b40e7 100644 --- a/mod/bigbluebuttonbn/tests/completion_test.php +++ b/mod/bigbluebuttonbn/tests/completion_test.php @@ -54,7 +54,7 @@ class completion_test extends \advanced_testcase { $completion = new custom_completion($bbactivitycm, $user->id); $result = $completion->get_overall_completion_state(); // No custom rules so complete by default. - $this->assertEquals(COMPLETION_INCOMPLETE, $result); + $this->assertEquals(COMPLETION_COMPLETE, $result); } /** @@ -213,6 +213,7 @@ class completion_test extends \advanced_testcase { $completion = new completion_info($this->get_course()); $completiondata = $completion->get_data($bbactivitycm); $this->assertEquals(1, $completiondata->viewed); - $this->assertEquals(COMPLETION_INCOMPLETE, $completiondata->completionstate); + // A view means COMPLETE. + $this->assertEquals(COMPLETION_COMPLETE, $completiondata->completionstate); } } diff --git a/mod/bigbluebuttonbn/tests/lib_test.php b/mod/bigbluebuttonbn/tests/lib_test.php index b1b535b51c2..4bd63f765cb 100644 --- a/mod/bigbluebuttonbn/tests/lib_test.php +++ b/mod/bigbluebuttonbn/tests/lib_test.php @@ -112,18 +112,14 @@ class lib_test extends \advanced_testcase { $user = $generator->create_user(); $this->setUser($user); - list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance(); - + list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance($this->get_course(), + ['completion' => 2, 'completionview' => 1]); $result = bigbluebuttonbn_user_outline($this->get_course(), $user, $bbactivitycm, $bbactivity); - $this->assertEquals((object) [], $result); - - // Now create a couple of logs. - $instance = instance::get_from_instanceid($bbactivity->id); - logger::log_meeting_joined_event($instance, 0); - logger::log_recording_played_event($instance, 1); + $this->assertEquals((object) ['info' => '', 'time' => 0], $result); + bigbluebuttonbn_view($bbactivity, $this->get_course(), $bbactivitycm, $bbactivitycontext); $result = bigbluebuttonbn_user_outline($this->get_course(), $user, $bbactivitycm, $bbactivity); - $this->assertStringContainsString(get_string('completionview_event_desc', 'mod_bigbluebuttonbn', 2), $result->info); + $this->assertStringContainsString(get_string('report_room_view', 'mod_bigbluebuttonbn'), $result->info); } /** @@ -137,19 +133,17 @@ class lib_test extends \advanced_testcase { $generator = $this->getDataGenerator(); $user = $generator->create_and_enrol($this->get_course()); - list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance(); + list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance($this->get_course(), + ['completion' => 2, 'completionview' => 1]); $this->setUser($user); // Now create a couple of logs. - $instance = instance::get_from_instanceid($bbactivity->id); - $recordings = $this->create_recordings_for_instance($instance, [['name' => "Pre-Recording 1"]]); - logger::log_meeting_joined_event($instance, 0); - logger::log_recording_played_event($instance, $recordings[0]->id); + bigbluebuttonbn_view($bbactivity, $this->get_course(), $bbactivitycm, $bbactivitycontext); ob_start(); bigbluebuttonbn_user_complete($this->get_course(), $user, $bbactivitycm, $bbactivity); $output = ob_get_contents(); ob_end_clean(); - $this->assertStringContainsString(get_string('completionview_event_desc', 'mod_bigbluebuttonbn', 2), $output); + $this->assertStringContainsString(get_string('report_room_view', 'mod_bigbluebuttonbn'), $output); } /** diff --git a/mod/bigbluebuttonbn/tests/local/helpers/user_info_test.php b/mod/bigbluebuttonbn/tests/local/helpers/user_info_test.php new file mode 100644 index 00000000000..79c841b7013 --- /dev/null +++ b/mod/bigbluebuttonbn/tests/local/helpers/user_info_test.php @@ -0,0 +1,85 @@ +. +namespace mod_bigbluebuttonbn\local\helpers; + +use mod_bigbluebuttonbn\instance; +use mod_bigbluebuttonbn\logger; +use mod_bigbluebuttonbn\test\testcase_helper_trait; + +/** + * User information printing test + * + * @package mod_bigbluebuttonbn + * @copyright 2022 - present, Blindside Networks Inc + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Laurent David (laurent@call-learning.fr) + * @covers \mod_bigbluebuttonbn\local\helpers\user_info + * @coversDefaultClass \mod_bigbluebuttonbn\local\helpers\user_info + */ +class user_info_test extends \advanced_testcase { + use testcase_helper_trait; + + /** + * Test user info outline + * + * @return void + */ + public function test_get_user_info_outline() { + $this->initialise_mock_server(); + $this->resetAfterTest(); + + $generator = $this->getDataGenerator(); + $user = $generator->create_and_enrol($this->get_course()); + list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance(); + $this->setUser($user); + + // Now create a couple of logs. + $instance = instance::get_from_instanceid($bbactivity->id); + $recordings = $this->create_recordings_for_instance($instance, [['name' => "Pre-Recording 1"]]); + logger::log_meeting_joined_event($instance, 0); + logger::log_recording_played_event($instance, $recordings[0]->id); + [$logjoins, $logtimes] = user_info::get_user_info_outline($this->get_course(), $user, $bbactivitycm); + $this->assertEquals([ + 'Has joined the room 1 time(s)', + 'Has played a recording 1 time(s)' + ], $logjoins); + $this->assertCount(2, $logtimes); + } + /** + * Test user info outline with several logs + * + * @return void + */ + public function test_get_user_info_outline_several_logs() { + $this->resetAfterTest(); + + $generator = $this->getDataGenerator(); + $user = $generator->create_and_enrol($this->get_course()); + list($bbactivitycontext, $bbactivitycm, $bbactivity) = $this->create_instance(); + $this->setUser($user); + + // Now create a couple of logs. + $instance = instance::get_from_instanceid($bbactivity->id); + logger::log_meeting_joined_event($instance, 0); + logger::log_meeting_joined_event($instance, 0); + + [$logjoins, $logtimes] = user_info::get_user_info_outline($this->get_course(), $user, $bbactivitycm); + $this->assertEquals([ + 'Has joined the room 2 time(s)', + ], $logjoins); + $this->assertCount(1, $logtimes); + } +}