See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
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 * Course completion status for a particular user/course 19 * 20 * @package core_completion 21 * @category completion 22 * @copyright 2009 Catalyst IT Ltd 23 * @author Aaron Barnes <aaronb@catalyst.net.nz> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 require_once($CFG->dirroot.'/completion/data_object.php'); 29 30 /** 31 * Course completion status for a particular user/course 32 * 33 * @package core_completion 34 * @category completion 35 * @copyright 2009 Catalyst IT Ltd 36 * @author Aaron Barnes <aaronb@catalyst.net.nz> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class completion_completion extends data_object { 40 41 /* @var string $table Database table name that stores completion information */ 42 public $table = 'course_completions'; 43 44 /* @var array $required_fields Array of required table fields, must start with 'id'. */ 45 public $required_fields = array('id', 'userid', 'course', 46 'timeenrolled', 'timestarted', 'timecompleted', 'reaggregate'); 47 48 /* @var int $userid User ID */ 49 public $userid; 50 51 /* @var int $course Course ID */ 52 public $course; 53 54 /* @var int Time of course enrolment {@link completion_completion::mark_enrolled()} */ 55 public $timeenrolled; 56 57 /** 58 * Time the user started their course completion {@link completion_completion::mark_inprogress()} 59 * @var int 60 */ 61 public $timestarted; 62 63 /* @var int Timestamp of course completion {@link completion_completion::mark_complete()} */ 64 public $timecompleted; 65 66 /* @var int Flag to trigger cron aggregation (timestamp) */ 67 public $reaggregate; 68 69 70 /** 71 * Finds and returns a data_object instance based on params. 72 * 73 * @param array $params associative arrays varname = >value 74 * @return data_object instance of data_object or false if none found. 75 */ 76 public static function fetch($params) { 77 $cache = cache::make('core', 'coursecompletion'); 78 79 $key = $params['userid'] . '_' . $params['course']; 80 if ($hit = $cache->get($key)) { 81 return $hit['value']; 82 } 83 84 $tocache = self::fetch_helper('course_completions', __CLASS__, $params); 85 $cache->set($key, ['value' => $tocache]); 86 return $tocache; 87 } 88 89 /** 90 * Return status of this completion 91 * 92 * @return bool 93 */ 94 public function is_complete() { 95 return (bool) $this->timecompleted; 96 } 97 98 /** 99 * Mark this user as started (or enrolled) in this course 100 * 101 * If the user is already marked as started, no change will occur 102 * 103 * @param integer $timeenrolled Time enrolled (optional) 104 * @return int|null id of completion record on successful update. 105 */ 106 public function mark_enrolled($timeenrolled = null) { 107 108 if ($this->timeenrolled === null) { 109 110 if ($timeenrolled === null) { 111 $timeenrolled = time(); 112 } 113 114 $this->timeenrolled = $timeenrolled; 115 } 116 117 return $this->_save(); 118 } 119 120 /** 121 * Mark this user as inprogress in this course 122 * 123 * If the user is already marked as inprogress, the time will not be changed 124 * 125 * @param integer $timestarted Time started (optional) 126 * @return int|null id of completion record on successful update. 127 */ 128 public function mark_inprogress($timestarted = null) { 129 130 $timenow = time(); 131 132 // Set reaggregate flag 133 $this->reaggregate = $timenow; 134 135 if (!$this->timestarted) { 136 137 if (!$timestarted) { 138 $timestarted = $timenow; 139 } 140 141 $this->timestarted = $timestarted; 142 } 143 144 return $this->_save(); 145 } 146 147 /** 148 * Mark this user complete in this course 149 * 150 * This generally happens when the required completion criteria 151 * in the course are complete. 152 * 153 * @param integer $timecomplete Time completed (optional) 154 * @return int|null id of completion record on successful update. 155 */ 156 public function mark_complete($timecomplete = null) { 157 global $USER; 158 159 // Never change a completion time. 160 if ($this->timecompleted) { 161 return null; 162 } 163 164 // Use current time if nothing supplied. 165 if (!$timecomplete) { 166 $timecomplete = time(); 167 } 168 169 // Set time complete. 170 $this->timecompleted = $timecomplete; 171 // Save record. 172 if ($result = $this->_save()) { 173 $data = $this->get_record_data(); 174 \core\event\course_completed::create_from_completion($data)->trigger(); 175 } 176 177 // Notify user. 178 $course = get_course($data->course); 179 $messagesubject = get_string('coursecompleted', 'completion'); 180 $a = [ 181 'coursename' => get_course_display_name_for_list($course), 182 'courselink' => (string) new moodle_url('/course/view.php', array('id' => $course->id)), 183 ]; 184 $messagebody = get_string('coursecompletedmessage', 'completion', $a); 185 $messageplaintext = html_to_text($messagebody); 186 187 $eventdata = new \core\message\message(); 188 $eventdata->courseid = $course->id; 189 $eventdata->component = 'moodle'; 190 $eventdata->name = 'coursecompleted'; 191 $eventdata->userfrom = core_user::get_noreply_user(); 192 $eventdata->userto = $data->userid; 193 $eventdata->notification = 1; 194 $eventdata->subject = $messagesubject; 195 $eventdata->fullmessage = $messageplaintext; 196 $eventdata->fullmessageformat = FORMAT_HTML; 197 $eventdata->fullmessagehtml = $messagebody; 198 $eventdata->smallmessage = $messageplaintext; 199 200 if ($courseimage = \core_course\external\course_summary_exporter::get_course_image($course)) { 201 $eventdata->customdata = [ 202 'notificationpictureurl' => $courseimage, 203 ]; 204 } 205 message_send($eventdata); 206 207 return $result; 208 } 209 210 /** 211 * Save course completion status 212 * 213 * This method creates a course_completions record if none exists 214 * @access private 215 * @return int|null id of completion record on successful update. 216 */ 217 private function _save() { 218 if ($this->timeenrolled === null) { 219 $this->timeenrolled = 0; 220 } 221 222 // Save record 223 if (isset($this->id)) { 224 $success = $this->update(); 225 } else { 226 // Make sure reaggregate field is not null 227 if (!$this->reaggregate) { 228 $this->reaggregate = 0; 229 } 230 231 // Make sure timestarted is not null 232 if (!$this->timestarted) { 233 $this->timestarted = 0; 234 } 235 236 $success = $this->insert(); 237 } 238 239 if ($success) { 240 // Update the cached record. 241 $cache = cache::make('core', 'coursecompletion'); 242 $data = $this->get_record_data(); 243 $key = $data->userid . '_' . $data->course; 244 $cache->set($key, ['value' => $data]); 245 return $this->id; 246 } 247 248 return null; 249 } 250 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body