Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 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 * 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 /** @var float user's course grade. */ 70 public $gradefinal; 71 72 /** 73 * Finds and returns a data_object instance based on params. 74 * 75 * @param array $params associative arrays varname = >value 76 * @return data_object instance of data_object or false if none found. 77 */ 78 public static function fetch($params) { 79 $cache = cache::make('core', 'coursecompletion'); 80 81 $key = $params['userid'] . '_' . $params['course']; 82 if ($hit = $cache->get($key)) { 83 return $hit['value']; 84 } 85 86 $tocache = self::fetch_helper('course_completions', __CLASS__, $params); 87 $cache->set($key, ['value' => $tocache]); 88 return $tocache; 89 } 90 91 /** 92 * Return status of this completion 93 * 94 * @return bool 95 */ 96 public function is_complete() { 97 return (bool) $this->timecompleted; 98 } 99 100 /** 101 * Mark this user as started (or enrolled) in this course 102 * 103 * If the user is already marked as started, no change will occur 104 * 105 * @param integer $timeenrolled Time enrolled (optional) 106 * @return int|null id of completion record on successful update. 107 */ 108 public function mark_enrolled($timeenrolled = null) { 109 110 if ($this->timeenrolled === null) { 111 112 if ($timeenrolled === null) { 113 $timeenrolled = time(); 114 } 115 116 $this->timeenrolled = $timeenrolled; 117 } 118 119 return $this->_save(); 120 } 121 122 /** 123 * Mark this user as inprogress in this course 124 * 125 * If the user is already marked as inprogress, the time will not be changed 126 * 127 * @param integer $timestarted Time started (optional) 128 * @return int|null id of completion record on successful update. 129 */ 130 public function mark_inprogress($timestarted = null) { 131 132 $timenow = time(); 133 134 // Set reaggregate flag 135 $this->reaggregate = $timenow; 136 137 if (!$this->timestarted) { 138 139 if (!$timestarted) { 140 $timestarted = $timenow; 141 } 142 143 $this->timestarted = $timestarted; 144 } 145 146 return $this->_save(); 147 } 148 149 /** 150 * Mark this user complete in this course 151 * 152 * This generally happens when the required completion criteria 153 * in the course are complete. 154 * 155 * @param integer $timecomplete Time completed (optional) 156 * @return int|null id of completion record on successful update. 157 */ 158 public function mark_complete($timecomplete = null) { 159 global $USER; 160 161 // Never change a completion time. 162 if ($this->timecompleted) { 163 return null; 164 } 165 166 // Use current time if nothing supplied. 167 if (!$timecomplete) { 168 $timecomplete = time(); 169 } 170 171 // Set time complete. 172 $this->timecompleted = $timecomplete; 173 // Save record. 174 if ($result = $this->_save()) { 175 $data = $this->get_record_data(); 176 \core\event\course_completed::create_from_completion($data)->trigger(); 177 } 178 179 // Notify user. 180 $course = get_course($data->course); 181 $messagesubject = get_string('coursecompleted', 'completion'); 182 $a = [ 183 'coursename' => get_course_display_name_for_list($course), 184 'courselink' => (string) new moodle_url('/course/view.php', array('id' => $course->id)), 185 ]; 186 $messagebody = get_string('coursecompletedmessage', 'completion', $a); 187 $messageplaintext = html_to_text($messagebody); 188 189 $eventdata = new \core\message\message(); 190 $eventdata->courseid = $course->id; 191 $eventdata->component = 'moodle'; 192 $eventdata->name = 'coursecompleted'; 193 $eventdata->userfrom = core_user::get_noreply_user(); 194 $eventdata->userto = $data->userid; 195 $eventdata->notification = 1; 196 $eventdata->subject = $messagesubject; 197 $eventdata->fullmessage = $messageplaintext; 198 $eventdata->fullmessageformat = FORMAT_HTML; 199 $eventdata->fullmessagehtml = $messagebody; 200 $eventdata->smallmessage = $messageplaintext; 201 202 if ($courseimage = \core_course\external\course_summary_exporter::get_course_image($course)) { 203 $eventdata->customdata = [ 204 'notificationpictureurl' => $courseimage, 205 ]; 206 } 207 message_send($eventdata); 208 209 return $result; 210 } 211 212 /** 213 * Save course completion status 214 * 215 * This method creates a course_completions record if none exists 216 * @access private 217 * @return int|null id of completion record on successful update. 218 */ 219 private function _save() { 220 if ($this->timeenrolled === null) { 221 $this->timeenrolled = 0; 222 } 223 224 // Save record 225 if (isset($this->id)) { 226 $success = $this->update(); 227 } else { 228 // Make sure reaggregate field is not null 229 if (!$this->reaggregate) { 230 $this->reaggregate = 0; 231 } 232 233 // Make sure timestarted is not null 234 if (!$this->timestarted) { 235 $this->timestarted = 0; 236 } 237 238 $success = $this->insert(); 239 } 240 241 if ($success) { 242 // Update the cached record. 243 $cache = cache::make('core', 'coursecompletion'); 244 $data = $this->get_record_data(); 245 $key = $data->userid . '_' . $data->course; 246 $cache->set($key, ['value' => $data]); 247 return $this->id; 248 } 249 250 return null; 251 } 252 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body