You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

369 lines
13 KiB

<?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/>.
/**
* @package mod_palestra
* @copyright 2021 Interlegis (https://www.interlegis.leg.br)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
function palestra_supports($feature) {
switch($feature) {
case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_ASSIGNMENT;
case FEATURE_GROUPS: return false;
case FEATURE_GROUPINGS: return false;
case FEATURE_MOD_INTRO: return true;
case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
case FEATURE_COMPLETION_HAS_RULES: return true;
case FEATURE_GRADE_HAS_GRADE: return true;
case FEATURE_BACKUP_MOODLE2: return true;
case FEATURE_SHOW_DESCRIPTION: return true;
default: return null;
}
}
function palestra_reset_userdata($data) {
// Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
// See MDL-9367.
return array();
}
function palestra_get_view_actions() {
return array('view','view all');
}
function palestra_get_post_actions() {
return array('update', 'add');
}
function palestra_add_instance($palestra, $mform = null) {
global $CFG, $DB;
require_once("$CFG->libdir/resourcelib.php");
$cmid = $palestra->coursemodule;
$palestra->timemodified = time();
$palestra->needsupdate = 1;
$palestra->id = $DB->insert_record('palestra', $palestra);
$DB->set_field('course_modules', 'instance', $palestra->id, array('id'=>$cmid));
$context = context_module::instance($cmid);
palestra_grade_item_update($palestra);
$completiontimeexpected = !empty($palestra->completionexpected) ? $palestra->completionexpected : null;
\core_completion\api::update_completion_date_event($cmid, 'palestra', $palestra->id, $completiontimeexpected);
return $palestra->id;
}
function palestra_update_instance($palestra, $mform) {
global $CFG, $DB;
require_once("$CFG->libdir/resourcelib.php");
$cmid = $palestra->coursemodule;
$palestra->timemodified = time();
$palestra->needsupdate = 1;
$palestra->id = $palestra->instance;
$DB->update_record('palestra', $palestra);
palestra_grade_item_update($palestra);
$completiontimeexpected = !empty($palestra->completionexpected) ? $palestra->completionexpected : null;
\core_completion\api::update_completion_date_event($cmid, 'palestra', $palestra->id, $completiontimeexpected);
return true;
}
function palestra_delete_instance($id) {
global $DB;
if (!$palestra = $DB->get_record('palestra', array('id'=>$id))) {
return false;
}
$cm = get_coursemodule_from_instance('palestra', $id);
\core_completion\api::update_completion_date_event($cm->id, 'palestra', $id, null);
$DB->delete_records('palestra', array('id'=>$palestra->id));
$DB->delete_records('palestra_presence', array('palestraid'=>$palestra->id));
return true;
}
function palestra_get_coursemodule_info($coursemodule) {
global $CFG, $DB;
require_once("$CFG->libdir/resourcelib.php");
if (!$palestra = $DB->get_record('palestra', array('id'=>$coursemodule->instance))) {
return NULL;
}
$info = new cached_cm_info();
$info->name = $palestra->name;
if ($coursemodule->showdescription) {
// Convert intro to html. Do not filter cached version, filters run at display time.
$info->content = format_module_intro('palestra', $palestra, $coursemodule->id, false);
}
return $info;
}
function palestra_view($palestra, $course, $cm, $context) {
$params = array(
'context' => $context,
'objectid' => $palestra->id
);
$event = \mod_palestra\event\course_module_viewed::create($params);
$event->add_record_snapshot('course_modules', $cm);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('palestra', $palestra);
$event->trigger();
// Completion.
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
}
function mod_palestra_core_calendar_provide_event_action(calendar_event $event,
\core_calendar\action_factory $factory, $userid = 0) {
global $USER;
if (empty($userid)) {
$userid = $USER->id;
}
$cm = get_fast_modinfo($event->courseid, $userid)->instances['palestra'][$event->instance];
$completion = new \completion_info($cm->get_course());
$completiondata = $completion->get_data($cm, false, $userid);
if ($completiondata->completionstate != COMPLETION_INCOMPLETE) {
return null;
}
return $factory->create_instance(
get_string('view'),
new \moodle_url('/mod/palestra/view.php', ['id' => $cm->id]),
1,
true
);
}
function palestra_grade_item_update($palestra, $grades=NULL) {
global $CFG;
if (!function_exists('grade_update')) { //workaround for buggy PHP versions
require_once($CFG->libdir.'/gradelib.php');
}
$params = array('itemname'=>$palestra->name, 'idnumber'=>$palestra->cmidnumber, 'needsupdate'=>1);
if ($palestra->grade == 0) {
$params['gradetype'] = GRADE_TYPE_NONE;
} else if ($palestra->grade > 0) {
$params['gradetype'] = GRADE_TYPE_VALUE;
$params['grademax'] = $palestra->grade;
$params['grademin'] = 0;
} else if ($palestra->grade < 0) {
$params['gradetype'] = GRADE_TYPE_SCALE;
$params['scaleid'] = -$palestra->grade;
}
if ($grades === 'reset') {
$params['reset'] = true;
$grades = NULL;
}
return grade_update('mod/palestra', $palestra->course, 'mod', 'palestra', $palestra->id, 0, $grades, $params);
}
function palestra_update_grades($palestra, $userid=0, $nullifnone=true) {
global $CFG, $DB;
require_once($CFG->libdir.'/gradelib.php');
$now = time();
if ($userid) {
$presences = $DB->get_records("palestra_presence", array("palestraid"=>$palestra->id, "userid"=>$userid), 'id, userid, starttime, lastcheck');
} else {
$presences = $DB->get_records_select("palestra_presence", "palestraid=? and lastcheck+? < ?", [$palestra->id, $palestra->duration*60, $now], 'userid, starttime', 'id, userid, starttime, lastcheck');
}
$audiences = array();
$minimal = $palestra->checkinterval * 60;
$user = null;
foreach($presences as $presence) {
# Compute only after palestra starts
if ($presence->starttime < $palestra->startdate) {
$presence->starttime = $palestra->startdate;
}
if ($user != $presence->userid) {
if ($user) {
$audiences[$user] = (isset($audiences[$user])?$audiences[$user]:0) + (max($end - $start, $minimal)/60);
}
$user = $presence->userid;
$start = $presence->starttime;
$end = $presence->lastcheck;
continue;
}
if ($presence->starttime < ($start + $minimal)) {
if ($end < $presence->lastcheck) {
$end = $presence->lastcheck;
}
} else {
$audiences[$user] = (isset($audiences[$user])?$audiences[$user]:0) + (max($end - $start, $minimal)/60);
$start = $presence->starttime;
$end = $presence->lastcheck;
}
}
if ($user) {
$audiences[$user] = (isset($audiences[$user])?$audiences[$user]:0) + (max($end - $start, $minimal)/60);
}
$grades = array();
foreach($audiences as $userid=>$presence_time) {
$presence_rate = $presence_time / $palestra->duration;
if ($presence_rate > 1.0) {
$presence_rate = 1.0;
}
$grade = new stdclass();
$grade->userid = $userid;
$grade->rawgrade = grade_floatval($palestra->grade * $presence_rate);
$grade->datesubmitted = $palestra->startdate;
$grade->dategraded = $palestra->startdate;
$grades[$userid] = $grade;
}
palestra_grade_item_update($palestra, $grades);
$DB->set_field('palestra', 'needsupdate', 0, array('id'=>$palestra->id));
}
function palestra_reset_gradebook($courseid, $type='') {
global $CFG, $DB;
$wheresql = '';
$params = array($courseid);
if ($type) {
$wheresql = "AND p.type=?";
$params[] = $type;
}
$sql = "SELECT p.*, cm.idnumber as cmidnumber, p.course as courseid
FROM {palestra} p, {course_modules} cm, {modules} m
WHERE m.name='palestra' AND m.id=cm.module AND cm.instance=p.id AND p.course=? $wheresql";
if ($palestras = $DB->get_records_sql($sql, $params)) {
foreach ($palestras as $palestra) {
palestra_grade_item_update($palestra, 'reset');
}
}
}
function palestra_get_user_grades($palestra, $userid = 0) {
global $CFG;
require_once($CFG->dirroot.'/rating/lib.php');
$ratingoptions = new stdClass;
$ratingoptions->component = 'mod_palestra';
$ratingoptions->ratingarea = 'post';
//need these to work backwards to get a context id. Is there a better way to get contextid from a module instance?
$ratingoptions->modulename = 'palestra';
$ratingoptions->moduleid = $palestra->id;
$ratingoptions->userid = $userid;
$ratingoptions->aggregationmethod = $palestra->assessed;
$ratingoptions->scaleid = $palestra->scale;
$ratingoptions->itemtable = 'palestra_posts';
$ratingoptions->itemtableusercolumn = 'userid';
$rm = new rating_manager();
return $rm->get_user_grades($ratingoptions);
}
function palestra_extend_settings_navigation($settings, $palestranode) {
global $PAGE, $CFG;
// We want to add these new nodes after the Edit settings node, and before the
// Locally assigned roles node. Of course, both of those are controlled by capabilities.
$keys = $palestranode->get_children_key_list();
$beforekey = null;
$i = array_search('modedit', $keys);
if ($i === false and array_key_exists(0, $keys)) {
$beforekey = $keys[0];
} else if (array_key_exists($i + 1, $keys)) {
$beforekey = $keys[$i + 1];
}
if (has_capability('mod/palestra:viewpresences', $PAGE->cm->context)) {
$url = new moodle_url('/mod/palestra/presences.php', array('cmid'=>$PAGE->cm->id));
$node = navigation_node::create(get_string('view_presences', 'palestra'),
$url,
navigation_node::TYPE_SETTING, null, 'mod_palestra_viewpresences');
$palestranode->add_node($node, $beforekey);
}
// if (has_capability('mod/quiz:manage', $PAGE->cm->context)) {
// $node = navigation_node::create(get_string('editquiz', 'quiz'),
// new moodle_url('/mod/quiz/edit.php', array('cmid'=>$PAGE->cm->id)),
// navigation_node::TYPE_SETTING, null, 'mod_quiz_edit',
// new pix_icon('t/edit', ''));
// $quiznode->add_node($node, $beforekey);
// }
// if (has_capability('mod/quiz:preview', $PAGE->cm->context)) {
// $url = new moodle_url('/mod/quiz/startattempt.php',
// array('cmid'=>$PAGE->cm->id, 'sesskey'=>sesskey()));
// $node = navigation_node::create(get_string('preview', 'quiz'), $url,
// navigation_node::TYPE_SETTING, null, 'mod_quiz_preview',
// new pix_icon('i/preview', ''));
// $quiznode->add_node($node, $beforekey);
// }
// if (has_any_capability(array('mod/quiz:viewreports', 'mod/quiz:grade'), $PAGE->cm->context)) {
// require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
// $reportlist = quiz_report_list($PAGE->cm->context);
// $url = new moodle_url('/mod/quiz/report.php',
// array('id' => $PAGE->cm->id, 'mode' => reset($reportlist)));
// $reportnode = $quiznode->add_node(navigation_node::create(get_string('results', 'quiz'), $url,
// navigation_node::TYPE_SETTING,
// null, null, new pix_icon('i/report', '')), $beforekey);
// foreach ($reportlist as $report) {
// $url = new moodle_url('/mod/quiz/report.php',
// array('id' => $PAGE->cm->id, 'mode' => $report));
// $reportnode->add_node(navigation_node::create(get_string($report, 'quiz_'.$report), $url,
// navigation_node::TYPE_SETTING,
// null, 'quiz_report_' . $report, new pix_icon('i/item', '')));
// }
// }
// question_extend_settings_navigation($quiznode, $PAGE->cm->context)->trim_if_empty();
}