Files
moodle/mod/bigbluebuttonbn/classes/completion/custom_completion.php
T
Marina Glancy b1c97381b4 MDL-76356 various: avoid implicit conversion to int
PHP before version 8.1 automatically converted to int if the function
parameter (or array key) is expected to be int. PHP 8.1 shows notice in
this case
2023-01-10 15:27:11 +01:00

297 lines
10 KiB
PHP

<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_bigbluebuttonbn\completion;
use core_completion\activity_custom_completion;
use mod_bigbluebuttonbn\instance;
use mod_bigbluebuttonbn\logger;
use moodle_exception;
use stdClass;
/**
* Class custom_completion
*
* @package mod_bigbluebuttonbn
* @copyright 2010 onwards, Blindside Networks Inc
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Laurent David (laurent@call-learning.fr)
*/
class custom_completion extends activity_custom_completion {
/**
* Filters for logs
*/
const FILTERS = [
'completionattendance' => [logger::EVENT_SUMMARY],
'completionengagementchats' => [logger::EVENT_SUMMARY],
'completionengagementtalks' => [logger::EVENT_SUMMARY],
'completionengagementraisehand' => [logger::EVENT_SUMMARY],
'completionengagementpollvotes' => [logger::EVENT_SUMMARY],
'completionengagementemojis' => [logger::EVENT_SUMMARY],
];
/**
* Get current state
*
* @param string $rule
* @return int
*/
public function get_state(string $rule): int {
// Get instance details.
$instance = instance::get_from_cmid($this->cm->id);
if (empty($instance)) {
throw new moodle_exception("Can't find bigbluebuttonbn instance {$this->cm->instance}");
}
// Default return value.
$returnedvalue = COMPLETION_INCOMPLETE;
$filters = self::FILTERS[$rule] ?? [logger::EVENT_SUMMARY];
$logs = logger::get_user_completion_logs($instance, $this->userid, $filters);
if (method_exists($this, "get_{$rule}_value")) {
$completionvalue = $this->aggregate_values($logs, self::class . "::get_{$rule}_value");
if ($completionvalue) {
// So in this case we check the value set in the module setting. If we go over the threshold, then
// this is complete.
$rulevalue = $instance->get_instance_var($rule);
if (!is_null($rulevalue)) {
if ($rulevalue <= $completionvalue) {
$returnedvalue = COMPLETION_COMPLETE;
}
} else {
// If there is at least a hit, we consider it as complete.
$returnedvalue = $completionvalue ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE;
}
}
}
return $returnedvalue;
}
/**
* Compute current state from logs.
*
* @param array $logs
* @param callable $logvaluegetter
* @return int the sum of all values for this particular event (it can be a duration or a number of hits)
*/
protected function aggregate_values(array $logs, callable $logvaluegetter): int {
if (empty($logs)) {
// As completion by engagement with $rulename hand was required, the activity hasn't been completed.
return 0;
}
$value = 0;
foreach ($logs as $log) {
$value += $logvaluegetter($log);
}
return $value;
}
/**
* Fetch the list of custom completion rules that this module defines.
*
* @return array
*/
public static function get_defined_custom_rules(): array {
return [
'completionattendance',
'completionengagementchats',
'completionengagementtalks',
'completionengagementraisehand',
'completionengagementpollvotes',
'completionengagementemojis',
];
}
/**
* Returns an associative array of the descriptions of custom completion rules.
*
* @return array
*/
public function get_custom_rule_descriptions(): array {
$completionengagementchats = $this->cm->customdata['customcompletionrules']['completionengagementchats'] ?? 1;
$completionengagementtalks = $this->cm->customdata['customcompletionrules']['completionengagementtalks'] ?? 1;
$completionengagementraisehand = $this->cm->customdata['customcompletionrules']['completionengagementraisehand'] ?? 1;
$completionengagementpollvotes = $this->cm->customdata['customcompletionrules']['completionengagementpollvotes'] ?? 1;
$completionengagementemojis = $this->cm->customdata['customcompletionrules']['completionengagementemojis'] ?? 1;
$completionattendance = $this->cm->customdata['customcompletionrules']['completionattendance'] ?? 1;
return [
'completionengagementchats' => get_string('completionengagementchats_desc', 'mod_bigbluebuttonbn',
$completionengagementchats),
'completionengagementtalks' => get_string('completionengagementtalks_desc', 'mod_bigbluebuttonbn',
$completionengagementtalks),
'completionengagementraisehand' => get_string('completionengagementraisehand_desc', 'mod_bigbluebuttonbn',
$completionengagementraisehand),
'completionengagementpollvotes' => get_string('completionengagementpollvotes_desc', 'mod_bigbluebuttonbn',
$completionengagementpollvotes),
'completionengagementemojis' => get_string('completionengagementemojis_desc', 'mod_bigbluebuttonbn',
$completionengagementemojis),
'completionattendance' => get_string('completionattendance_desc', 'mod_bigbluebuttonbn',
$completionattendance),
];
}
/**
* Returns an array of all completion rules, in the order they should be displayed to users.
*
* @return array
*/
public function get_sort_order(): array {
return [
'completionview',
'completionengagementchats',
'completionengagementtalks',
'completionengagementraisehand',
'completionengagementpollvotes',
'completionengagementemojis',
'completionattendance',
];
}
/**
* Get current states of completion in a human-friendly version
*
* @return string[]
*/
public function get_printable_states(): array {
$result = [];
foreach ($this->get_available_custom_rules() as $rule) {
$result[] = $this->get_printable_state($rule);
}
return $result;
}
/**
* Get current states of completion for a rule in a human-friendly version
*
* @param string $rule
* @return string
*/
private function get_printable_state(string $rule): string {
// Get instance details.
$instance = instance::get_from_cmid($this->cm->id);
if (empty($instance)) {
throw new moodle_exception("Can't find bigbluebuttonbn instance {$this->cm->instance}");
}
$summary = "";
$filters = self::FILTERS[$rule] ?? [logger::EVENT_SUMMARY];
$logs = logger::get_user_completion_logs($instance, $this->userid, $filters);
if (method_exists($this, "get_{$rule}_value")) {
$summary = get_string(
$rule . '_event_desc',
'mod_bigbluebuttonbn',
$this->aggregate_values($logs, self::class . "::get_{$rule}_value")
);
}
return $summary;
}
/**
* Get current state in a friendly version
*
* @param string $rule
* @return string
*/
public function get_last_log_timestamp(string $rule): string {
// Get instance details.
$instance = instance::get_from_cmid($this->cm->id);
if (empty($instance)) {
throw new moodle_exception("Can't find bigbluebuttonbn instance {$this->cm->instance}");
}
$filters = self::FILTERS[$rule] ?? [logger::EVENT_SUMMARY];
return logger::get_user_completion_logs_max_timestamp($instance, $this->userid, $filters);
}
/**
* Get attendance summary value
*
* @param stdClass $log
* @return int
*/
protected static function get_completionattendance_value(stdClass $log): int {
$summary = json_decode($log->meta);
return empty($summary->data->duration) ? 0 : (int)($summary->data->duration / 60);
}
/**
* Get general completion engagement value
*
* @param stdClass $log
* @return int
*/
protected static function get_completionengagementchats_value(stdClass $log): int {
return self::get_completionengagement_value($log, 'chats');
}
/**
* Get general completion engagement value
*
* @param stdClass $log
* @return int
*/
protected static function get_completionengagementtalks_value(stdClass $log): int {
return self::get_completionengagement_value($log, 'talks');
}
/**
* Get general completion engagement value
*
* @param stdClass $log
* @return int
*/
protected static function get_completionengagementraisehand_value(stdClass $log): int {
return self::get_completionengagement_value($log, 'raisehand');
}
/**
* Get general completion engagement value
*
* @param stdClass $log
* @return int
*/
protected static function get_completionengagementpollvotes_value(stdClass $log): int {
return self::get_completionengagement_value($log, 'poll_votes');
}
/**
* Get general completion engagement value
*
* @param stdClass $log
* @return int
*/
protected static function get_completionengagementemojis_value(stdClass $log): int {
return self::get_completionengagement_value($log, 'emojis');
}
/**
* Get general completion engagement value
*
* @param stdClass $log
* @param string $type
* @return int
*/
protected static function get_completionengagement_value(stdClass $log, string $type): int {
$summary = json_decode($log->meta);
return intval($summary->data->engagement->$type ?? 0);
}
}