. /** * @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(); }