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 critieria - completion after specific duration from course enrolment 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 29 /** 30 * Course completion critieria - completion after specific duration from course enrolment 31 * 32 * @package core_completion 33 * @category completion 34 * @copyright 2009 Catalyst IT Ltd 35 * @author Aaron Barnes <aaronb@catalyst.net.nz> 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class completion_criteria_duration extends completion_criteria { 39 40 /* @var int Criteria type constant [COMPLETION_CRITERIA_TYPE_DURATION] */ 41 public $criteriatype = COMPLETION_CRITERIA_TYPE_DURATION; 42 43 /** 44 * Finds and returns a data_object instance based on params. 45 * 46 * @param array $params associative arrays varname=>value 47 * @return data_object data_object instance or false if none found. 48 */ 49 public static function fetch($params) { 50 $params['criteriatype'] = COMPLETION_CRITERIA_TYPE_DURATION; 51 return self::fetch_helper('course_completion_criteria', __CLASS__, $params); 52 } 53 54 /** 55 * Add appropriate form elements to the critieria form 56 * 57 * @param moodleform $mform Moodle forms object 58 * @param stdClass $data not used 59 */ 60 public function config_form_display(&$mform, $data = null) { 61 62 $mform->addElement('checkbox', 'criteria_duration', get_string('enable')); 63 64 // Populate the duration length drop down. 65 $thresholdmenu = array( 66 // We have strings for 1 - 6 days in the core. 67 86400 => get_string('secondstotime86400', 'core'), 68 172800 => get_string('secondstotime172800', 'core'), 69 259200 => get_string('secondstotime259200', 'core'), 70 345600 => get_string('secondstotime345600', 'core'), 71 432000 => get_string('secondstotime432000', 'core'), 72 518400 => get_string('secondstotime518400', 'core'), 73 518400 => get_string('secondstotime518400', 'core'), 74 ); 75 // Append strings for 7 - 30 days (step by 1 day). 76 for ($i = 7; $i <= 30; $i++) { 77 $seconds = $i * DAYSECS; 78 $thresholdmenu[$seconds] = get_string('numdays', 'core', $i); 79 } 80 // Append strings for 40 - 180 days (step by 10 days). 81 for ($i = 40; $i <= 180; $i = $i + 10) { 82 $seconds = $i * DAYSECS; 83 $thresholdmenu[$seconds] = get_string('numdays', 'core', $i); 84 } 85 // Append string for 1 year. 86 $thresholdmenu[365 * DAYSECS] = get_string('numdays', 'core', 365); 87 88 $mform->addElement('select', 'criteria_duration_days', get_string('enrolmentdurationlength', 'core_completion'), $thresholdmenu); 89 $mform->disabledIf('criteria_duration_days', 'criteria_duration'); 90 91 if ($this->id) { 92 $mform->setDefault('criteria_duration', 1); 93 $mform->setDefault('criteria_duration_days', $this->enrolperiod); 94 } 95 } 96 97 /** 98 * Update the criteria information stored in the database 99 * 100 * @param stdClass $data Form data 101 */ 102 public function update_config(&$data) { 103 if (!empty($data->criteria_duration)) { 104 $this->course = $data->id; 105 $this->enrolperiod = $data->criteria_duration_days; 106 $this->insert(); 107 } 108 } 109 110 /** 111 * Get the time this user was enroled 112 * 113 * @param completion_completion $completion 114 * @return int 115 */ 116 private function get_timeenrolled($completion) { 117 global $DB; 118 119 return $DB->get_field_sql(' 120 SELECT eu.timestart 121 FROM {user_enrolments} eu 122 JOIN {enrol} e ON eu.enrolid = e.id 123 WHERE e.courseid = ? 124 AND eu.userid = ?', array($this->course, $completion->userid)); 125 } 126 127 /** 128 * Review this criteria and decide if the user has completed 129 * 130 * @param completion_completion $completion The user's completion record 131 * @param bool $mark Optionally set false to not save changes to database 132 * @return bool 133 */ 134 public function review($completion, $mark = true) { 135 $timeenrolled = $this->get_timeenrolled($completion); 136 137 // If duration since enrollment has passed 138 if (!$this->enrolperiod || !$timeenrolled) { 139 return false; 140 } 141 142 if (time() > ($timeenrolled + $this->enrolperiod)) { 143 if ($mark) { 144 $completion->mark_complete(); 145 } 146 147 return true; 148 } 149 150 return false; 151 } 152 153 /** 154 * Return criteria title for display in reports 155 * 156 * @return string 157 */ 158 public function get_title() { 159 return get_string('enrolmentduration', 'completion'); 160 } 161 162 /** 163 * Return a more detailed criteria title for display in reports 164 * 165 * @return string 166 */ 167 public function get_title_detailed() { 168 return get_string('xdays', 'completion', ceil($this->enrolperiod / (60 * 60 * 24))); 169 } 170 171 /** 172 * Return criteria type title for display in reports 173 * 174 * @return string 175 */ 176 public function get_type_title() { 177 return get_string('days', 'completion'); 178 } 179 180 /** 181 * Return criteria status text for display in reports 182 * 183 * @param completion_completion $completion The user's completion record 184 * @return string 185 */ 186 public function get_status($completion) { 187 $timeenrolled = $this->get_timeenrolled($completion); 188 $timeleft = $timeenrolled + $this->enrolperiod - time(); 189 $enrolperiod = ceil($this->enrolperiod / (60 * 60 * 24)); 190 191 $daysleft = ceil($timeleft / (60 * 60 * 24)); 192 193 return get_string('daysoftotal', 'completion', array( 194 'days' => $daysleft > 0 ? $daysleft : 0, 'total' => $enrolperiod)); 195 } 196 197 /** 198 * Find user's who have completed this criteria 199 */ 200 public function cron() { 201 global $DB; 202 203 /* 204 * Get all users who match meet this criteria 205 * 206 * We can safely ignore duplicate enrolments for 207 * a user in a course here as we only care if 208 * one of the enrolments has passed the set 209 * duration. 210 */ 211 $sql = ' 212 SELECT 213 c.id AS course, 214 cr.id AS criteriaid, 215 u.id AS userid, 216 ue.timestart AS otimestart, 217 (ue.timestart + cr.enrolperiod) AS ctimestart, 218 ue.timecreated AS otimeenrolled, 219 (ue.timecreated + cr.enrolperiod) AS ctimeenrolled 220 FROM 221 {user} u 222 INNER JOIN 223 {user_enrolments} ue 224 ON ue.userid = u.id 225 INNER JOIN 226 {enrol} e 227 ON e.id = ue.enrolid 228 INNER JOIN 229 {course} c 230 ON c.id = e.courseid 231 INNER JOIN 232 {course_completion_criteria} cr 233 ON c.id = cr.course 234 LEFT JOIN 235 {course_completion_crit_compl} cc 236 ON cc.criteriaid = cr.id 237 AND cc.userid = u.id 238 WHERE 239 cr.criteriatype = '.COMPLETION_CRITERIA_TYPE_DURATION.' 240 AND c.enablecompletion = 1 241 AND cc.id IS NULL 242 AND 243 ( 244 ue.timestart > 0 AND ue.timestart + cr.enrolperiod < ? 245 OR ue.timecreated > 0 AND ue.timecreated + cr.enrolperiod < ? 246 ) 247 '; 248 249 // Loop through completions, and mark as complete 250 $now = time(); 251 $rs = $DB->get_recordset_sql($sql, array($now, $now)); 252 foreach ($rs as $record) { 253 $completion = new completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY); 254 255 // Use time start if not 0, otherwise use timeenrolled 256 if ($record->otimestart) { 257 $completion->mark_complete($record->ctimestart); 258 } else { 259 $completion->mark_complete($record->ctimeenrolled); 260 } 261 } 262 $rs->close(); 263 } 264 265 /** 266 * Return criteria progress details for display in reports 267 * 268 * @param completion_completion $completion The user's completion record 269 * @return array An array with the following keys: 270 * type, criteria, requirement, status 271 */ 272 public function get_details($completion) { 273 $details = array(); 274 $details['type'] = get_string('periodpostenrolment', 'completion'); 275 $details['criteria'] = get_string('remainingenroledfortime', 'completion'); 276 $details['requirement'] = get_string('xdays', 'completion', ceil($this->enrolperiod / (60*60*24))); 277 278 // Get status 279 $timeenrolled = $this->get_timeenrolled($completion); 280 $timepassed = time() - $timeenrolled; 281 $details['status'] = get_string('xdays', 'completion', floor($timepassed / (60*60*24))); 282 283 return $details; 284 } 285 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body