Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Contains class containing completion API. 19 * 20 * @package core_completion 21 * @copyright 2017 Mark Nelson <markn@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_completion; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Class containing completion API. 31 * 32 * @package core_completion 33 * @copyright 2017 Mark Nelson <markn@moodle.com> 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class api { 37 38 /** 39 * @var string The completion expected on event. 40 */ 41 const COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED = 'expectcompletionon'; 42 43 /** 44 * Creates, updates or deletes an event for the expected completion date. 45 * 46 * @param int $cmid The course module id 47 * @param string $modulename The name of the module (eg. assign, quiz) 48 * @param \stdClass|int $instanceorid The instance object or ID. 49 * @param int|null $completionexpectedtime The time completion is expected, null if not set 50 * @return bool 51 */ 52 public static function update_completion_date_event($cmid, $modulename, $instanceorid, $completionexpectedtime) { 53 global $CFG, $DB; 54 55 // Required for calendar constant CALENDAR_EVENT_TYPE_ACTION. 56 require_once($CFG->dirroot . '/calendar/lib.php'); 57 58 $instance = null; 59 if (is_object($instanceorid)) { 60 $instance = $instanceorid; 61 } else { 62 $instance = $DB->get_record($modulename, array('id' => $instanceorid), '*', IGNORE_MISSING); 63 } 64 if (!$instance) { 65 return false; 66 } 67 $course = get_course($instance->course); 68 69 $completion = new \completion_info($course); 70 71 // Can not create/update an event if completion is disabled. 72 if (!$completion->is_enabled() && $completionexpectedtime !== null) { 73 return true; 74 } 75 76 // Create the \stdClass we will be using for our language strings. 77 $lang = new \stdClass(); 78 $lang->modulename = get_string('pluginname', $modulename); 79 $lang->instancename = $instance->name; 80 81 // Create the calendar event. 82 $event = new \stdClass(); 83 $event->type = CALENDAR_EVENT_TYPE_ACTION; 84 $event->eventtype = self::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED; 85 if ($event->id = $DB->get_field('event', 'id', array('modulename' => $modulename, 86 'instance' => $instance->id, 'eventtype' => $event->eventtype))) { 87 if ($completionexpectedtime !== null) { 88 // Calendar event exists so update it. 89 $event->name = get_string('completionexpectedfor', 'completion', $lang); 90 $event->description = format_module_intro($modulename, $instance, $cmid, false); 91 $event->format = FORMAT_HTML; 92 $event->timestart = $completionexpectedtime; 93 $event->timesort = $completionexpectedtime; 94 $event->visible = instance_is_visible($modulename, $instance); 95 $event->timeduration = 0; 96 97 $calendarevent = \calendar_event::load($event->id); 98 $calendarevent->update($event, false); 99 } else { 100 // Calendar event is no longer needed. 101 $calendarevent = \calendar_event::load($event->id); 102 $calendarevent->delete(); 103 } 104 } else { 105 // Event doesn't exist so create one. 106 if ($completionexpectedtime !== null) { 107 $event->name = get_string('completionexpectedfor', 'completion', $lang); 108 $event->description = format_module_intro($modulename, $instance, $cmid, false); 109 $event->format = FORMAT_HTML; 110 $event->courseid = $instance->course; 111 $event->groupid = 0; 112 $event->userid = 0; 113 $event->modulename = $modulename; 114 $event->instance = $instance->id; 115 $event->timestart = $completionexpectedtime; 116 $event->timesort = $completionexpectedtime; 117 $event->visible = instance_is_visible($modulename, $instance); 118 $event->timeduration = 0; 119 120 \calendar_event::create($event, false); 121 } 122 } 123 124 return true; 125 } 126 127 /** 128 * Mark users who completed course based on activity criteria. 129 * @param array $userdata If set only marks specified user in given course else checks all courses/users. 130 * @return int Completion record id if $userdata is set, 0 else. 131 * @since Moodle 4.0 132 */ 133 public static function mark_course_completions_activity_criteria($userdata = null): int { 134 global $DB; 135 136 // Get all users who meet this criteria 137 $sql = "SELECT DISTINCT c.id AS course, 138 cr.id AS criteriaid, 139 ra.userid AS userid, 140 mc.timemodified AS timecompleted 141 FROM {course_completion_criteria} cr 142 INNER JOIN {course} c ON cr.course = c.id 143 INNER JOIN {context} con ON con.instanceid = c.id 144 INNER JOIN {role_assignments} ra ON ra.contextid = con.id 145 INNER JOIN {course_modules} cm ON cm.id = cr.moduleinstance 146 INNER JOIN {course_modules_completion} mc ON mc.coursemoduleid = cr.moduleinstance AND mc.userid = ra.userid 147 LEFT JOIN {course_completion_crit_compl} cc ON cc.criteriaid = cr.id AND cc.userid = ra.userid 148 WHERE cr.criteriatype = :criteriatype 149 AND con.contextlevel = :contextlevel 150 AND c.enablecompletion = 1 151 AND cc.id IS NULL 152 AND ( 153 mc.completionstate = :completionstate 154 OR (cm.completionpassgrade = 1 AND mc.completionstate = :completionstatepass1) 155 OR (cm.completionpassgrade = 0 AND (mc.completionstate = :completionstatepass2 156 OR mc.completionstate = :completionstatefail)) 157 )"; 158 159 $params = [ 160 'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY, 161 'contextlevel' => CONTEXT_COURSE, 162 'completionstate' => COMPLETION_COMPLETE, 163 'completionstatepass1' => COMPLETION_COMPLETE_PASS, 164 'completionstatepass2' => COMPLETION_COMPLETE_PASS, 165 'completionstatefail' => COMPLETION_COMPLETE_FAIL 166 ]; 167 168 if ($userdata) { 169 $params['courseid'] = $userdata['courseid']; 170 $params['userid'] = $userdata['userid']; 171 $sql .= " AND c.id = :courseid AND ra.userid = :userid"; 172 // Mark as complete. 173 $record = $DB->get_record_sql($sql, $params); 174 if ($record) { 175 $completion = new \completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY); 176 $result = $completion->mark_complete($record->timecompleted); 177 return $result; 178 } 179 } else { 180 // Loop through completions, and mark as complete. 181 $rs = $DB->get_recordset_sql($sql, $params); 182 foreach ($rs as $record) { 183 $completion = new \completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY); 184 $completion->mark_complete($record->timecompleted); 185 } 186 $rs->close(); 187 } 188 return 0; 189 } 190 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body