Commit | Line | Data |
---|---|---|
2be4d090 MD |
1 | <?php |
2 | ||
3 | // This file is part of Moodle - http://moodle.org/ | |
4 | // | |
5 | // Moodle is free software: you can redistribute it and/or modify | |
6 | // it under the terms of the GNU General Public License as published by | |
7 | // the Free Software Foundation, either version 3 of the License, or | |
8 | // (at your option) any later version. | |
9 | // | |
10 | // Moodle is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | // GNU General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU General Public License | |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
18 | /** | |
19 | * Course completion critieria - completion after specific duration from course enrolment | |
20 | * | |
21 | * @package moodlecore | |
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 | class completion_criteria_duration extends completion_criteria { | |
27 | ||
28 | /** | |
29 | * Criteria type constant | |
30 | * @var int | |
31 | */ | |
32 | public $criteriatype = COMPLETION_CRITERIA_TYPE_DURATION; | |
33 | ||
34 | /** | |
35 | * Finds and returns a data_object instance based on params. | |
36 | * @static abstract | |
37 | * | |
38 | * @param array $params associative arrays varname=>value | |
39 | * @return object data_object instance or false if none found. | |
40 | */ | |
41 | public static function fetch($params) { | |
42 | $params['criteriatype'] = COMPLETION_CRITERIA_TYPE_DURATION; | |
43 | return self::fetch_helper('course_completion_criteria', __CLASS__, $params); | |
44 | } | |
45 | ||
46 | /** | |
47 | * Add appropriate form elements to the critieria form | |
48 | * @access public | |
49 | * @param object $mform Moodle forms object | |
50 | * @param mixed $data optional | |
51 | * @return void | |
52 | */ | |
53 | public function config_form_display(&$mform, $data = null) { | |
54 | ||
55 | $mform->addElement('checkbox', 'criteria_duration', get_string('enable')); | |
56 | ||
57 | $thresholdmenu=array(); | |
58 | for ($i=1; $i<=30; $i++) { | |
59 | $seconds = $i * 86400; | |
60 | $thresholdmenu[$seconds] = get_string('numdays', '', $i); | |
61 | } | |
62 | $mform->addElement('select', 'criteria_duration_days', get_string('daysafterenrolment', 'completion'), $thresholdmenu); | |
63 | ||
64 | if ($this->id) { | |
65 | $mform->setDefault('criteria_duration', 1); | |
66 | $mform->setDefault('criteria_duration_days', $this->enrolperiod); | |
67 | } | |
68 | } | |
69 | ||
70 | /** | |
71 | * Update the criteria information stored in the database | |
72 | * @access public | |
73 | * @param array $data Form data | |
74 | * @return void | |
75 | */ | |
76 | public function update_config(&$data) { | |
77 | ||
78 | if (!empty($data->criteria_duration)) { | |
79 | $this->course = $data->id; | |
80 | $this->enrolperiod = $data->criteria_duration_days; | |
81 | $this->insert(); | |
82 | } | |
83 | } | |
84 | ||
85 | /** | |
86 | * Get the time this user was enroled | |
87 | * @param object $completion | |
88 | * @return int | |
89 | */ | |
90 | private function get_timeenrolled($completion) { | |
91 | global $DB; | |
92 | ||
b58f4df6 AB |
93 | return $DB->get_field_sql(' |
94 | SELECT eu.timestart | |
95 | FROM {user_enrolments} eu | |
96 | JOIN {enrol} e ON eu.enrolid = e.id | |
97 | WHERE e.courseid = ? | |
98 | AND eu.userid = ?', array($this->course, $completion->userid)); | |
2be4d090 MD |
99 | } |
100 | ||
101 | /** | |
102 | * Review this criteria and decide if the user has completed | |
103 | * @access public | |
104 | * @param object $completion The user's completion record | |
105 | * @param boolean $mark Optionally set false to not save changes to database | |
106 | * @return boolean | |
107 | */ | |
108 | public function review($completion, $mark = true) { | |
109 | $timeenrolled = $this->get_timeenrolled($completion); | |
110 | ||
111 | // If duration since enrollment has passed | |
112 | if (!$this->enrolperiod || !$timeenrolled) { | |
113 | return false; | |
114 | } | |
115 | ||
116 | if (time() > ($timeenrolled + $this->enrolperiod)) { | |
117 | if ($mark) { | |
118 | $completion->mark_complete(); | |
119 | } | |
120 | ||
121 | return true; | |
122 | } | |
123 | ||
124 | return false; | |
125 | } | |
126 | ||
127 | /** | |
128 | * Return criteria title for display in reports | |
129 | * @access public | |
130 | * @return string | |
131 | */ | |
132 | public function get_title() { | |
133 | return get_string('enrolmentduration', 'completion'); | |
134 | } | |
135 | ||
136 | /** | |
137 | * Return a more detailed criteria title for display in reports | |
138 | * @access public | |
139 | * @return string | |
140 | */ | |
141 | public function get_title_detailed() { | |
142 | return ceil($this->enrolperiod / (60 * 60 * 24)) . ' days'; | |
143 | } | |
144 | ||
145 | /** | |
146 | * Return criteria type title for display in reports | |
147 | * @access public | |
148 | * @return string | |
149 | */ | |
150 | public function get_type_title() { | |
151 | return get_string('days', 'completion'); | |
152 | } | |
153 | ||
154 | /** | |
155 | * Return criteria status text for display in reports | |
156 | * @access public | |
157 | * @param object $completion The user's completion record | |
158 | * @return string | |
159 | */ | |
160 | public function get_status($completion) { | |
161 | $timeenrolled = $this->get_timeenrolled($completion); | |
162 | $timeleft = $timeenrolled + $this->enrolperiod - time(); | |
163 | $enrolperiod = ceil($this->enrolperiod / (60 * 60 * 24)); | |
164 | ||
165 | $daysleft = ceil($timeleft / (60 * 60 * 24)); | |
166 | ||
167 | return ($daysleft > 0 ? $daysleft : 0).' of '.$enrolperiod; | |
168 | } | |
169 | ||
170 | /** | |
171 | * Find user's who have completed this criteria | |
172 | * @access public | |
173 | * @return void | |
174 | */ | |
175 | public function cron() { | |
176 | global $DB; | |
177 | ||
89482538 AB |
178 | /* |
179 | * Get all users who match meet this criteria | |
180 | * | |
181 | * We can safely ignore duplicate enrolments for | |
182 | * a user in a course here as we only care if | |
183 | * one of the enrolments has passed the set | |
184 | * duration. | |
185 | */ | |
2be4d090 | 186 | $sql = ' |
89482538 | 187 | SELECT |
2be4d090 | 188 | c.id AS course, |
2be4d090 | 189 | cr.id AS criteriaid, |
89482538 AB |
190 | u.id AS userid, |
191 | ue.timestart AS otimestart, | |
192 | (ue.timestart + cr.enrolperiod) AS ctimestart, | |
fbc133e5 AB |
193 | ue.timecreated AS otimeenrolled, |
194 | (ue.timecreated + cr.enrolperiod) AS ctimeenrolled | |
2be4d090 | 195 | FROM |
89482538 | 196 | {user} u |
2be4d090 | 197 | INNER JOIN |
89482538 AB |
198 | {user_enrolments} ue |
199 | ON ue.userid = u.id | |
2be4d090 | 200 | INNER JOIN |
89482538 AB |
201 | {enrol} e |
202 | ON e.id = ue.enrolid | |
2be4d090 | 203 | INNER JOIN |
89482538 AB |
204 | {course} c |
205 | ON c.id = e.courseid | |
206 | INNER JOIN | |
207 | {course_completion_criteria} cr | |
208 | ON c.id = cr.course | |
2be4d090 MD |
209 | LEFT JOIN |
210 | {course_completion_crit_compl} cc | |
211 | ON cc.criteriaid = cr.id | |
89482538 | 212 | AND cc.userid = u.id |
2be4d090 MD |
213 | WHERE |
214 | cr.criteriatype = '.COMPLETION_CRITERIA_TYPE_DURATION.' | |
2be4d090 MD |
215 | AND c.enablecompletion = 1 |
216 | AND cc.id IS NULL | |
89482538 AB |
217 | AND |
218 | ( | |
219 | ue.timestart > 0 AND ue.timestart + cr.enrolperiod < ? | |
fbc133e5 | 220 | OR ue.timecreated > 0 AND ue.timecreated + cr.enrolperiod < ? |
89482538 | 221 | ) |
2be4d090 MD |
222 | '; |
223 | ||
224 | // Loop through completions, and mark as complete | |
89482538 | 225 | $now = time(); |
419178d7 EL |
226 | $rs = $DB->get_recordset_sql($sql, array($now, $now)); |
227 | foreach ($rs as $record) { | |
2be4d090 | 228 | |
419178d7 | 229 | $completion = new completion_criteria_completion((array)$record); |
89482538 | 230 | |
419178d7 EL |
231 | // Use time start if not 0, otherwise use timeenrolled |
232 | if ($record->otimestart) { | |
233 | $completion->mark_complete($record->ctimestart); | |
234 | } else { | |
235 | $completion->mark_complete($record->ctimeenrolled); | |
2be4d090 | 236 | } |
2be4d090 | 237 | } |
419178d7 | 238 | $rs->close(); |
2be4d090 MD |
239 | } |
240 | ||
241 | /** | |
242 | * Return criteria progress details for display in reports | |
243 | * @access public | |
244 | * @param object $completion The user's completion record | |
245 | * @return array | |
246 | */ | |
247 | public function get_details($completion) { | |
248 | $details = array(); | |
249 | $details['type'] = get_string('periodpostenrolment', 'completion'); | |
250 | $details['criteria'] = get_string('remainingenroledfortime', 'completion'); | |
251 | $details['requirement'] = get_string('xdays', 'completion', ceil($this->enrolperiod / (60*60*24))); | |
252 | ||
253 | // Get status | |
254 | $timeenrolled = $this->get_timeenrolled($completion); | |
255 | $timepassed = time() - $timeenrolled; | |
256 | $details['status'] = get_string('xdays', 'completion', floor($timepassed / (60*60*24))); | |
257 | ||
258 | return $details; | |
259 | } | |
260 | } |