course completion: MDL-2631 Fix rare mark_completed bug
[moodle.git] / lib / completion / completion_completion.php
CommitLineData
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/**
20 * Course completion status for a particular user/course
21 *
22 * @package moodlecore
23 * @copyright 2009 Catalyst IT Ltd
24 * @author Aaron Barnes <aaronb@catalyst.net.nz>
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 */
27require_once($CFG->libdir.'/completion/data_object.php');
28
29
30/**
31 * Course completion status for a particular user/course
32 */
33class completion_completion extends data_object {
34
35 /**
36 * DB Table
37 * @var string $table
38 */
39 public $table = 'course_completions';
40
41 /**
42 * Array of required table fields, must start with 'id'.
43 * @var array $required_fields
44 */
45 public $required_fields = array('id', 'userid', 'course', 'deleted', 'timenotified',
46 'timeenrolled', 'timestarted', 'timecompleted', 'reaggregate');
47
48 /**
49 * User ID
50 * @access public
51 * @var int
52 */
53 public $userid;
54
55 /**
56 * Course ID
57 * @access public
58 * @var int
59 */
60 public $course;
61
62 /**
63 * Set to 1 if this record has been deleted
64 * @access public
65 * @var int
66 */
67 public $deleted;
68
69 /**
70 * Timestamp the interested parties were notified
71 * of this user's completion
72 * @access public
73 * @var int
74 */
75 public $timenotified;
76
77 /**
78 * Time of course enrolment
79 * @see completion_completion::mark_enrolled()
80 * @access public
81 * @var int
82 */
83 public $timeenrolled;
84
85 /**
86 * Time the user started their course completion
87 * @see completion_completion::mark_inprogress()
88 * @access public
89 * @var int
90 */
91 public $timestarted;
92
93 /**
94 * Timestamp of course completion
95 * @see completion_completion::mark_complete()
96 * @access public
97 * @var int
98 */
99 public $timecompleted;
100
101 /**
102 * Flag to trigger cron aggregation (timestamp)
103 * @access public
104 * @var int
105 */
106 public $reaggregate;
107
108
109 /**
110 * Finds and returns a data_object instance based on params.
111 * @static abstract
112 *
113 * @param array $params associative arrays varname=>value
114 * @return object data_object instance or false if none found.
115 */
116 public static function fetch($params) {
117 $params['deleted'] = null;
118 return self::fetch_helper('course_completions', __CLASS__, $params);
119 }
120
121 /**
122 * Return status of this completion
123 * @access public
124 * @return boolean
125 */
126 public function is_complete() {
127 return (bool) $this->timecompleted;
128 }
129
130 /**
131 * Mark this user as started (or enrolled) in this course
132 *
133 * If the user is already marked as started, no change will occur
134 *
135 * @access public
136 * @param integer $timeenrolled Time enrolled (optional)
137 * @return void
138 */
139 public function mark_enrolled($timeenrolled = null) {
140
89482538 141 if ($this->timeenrolled === null) {
2be4d090 142
89482538 143 if ($timeenrolled === null) {
2be4d090
MD
144 $timeenrolled = time();
145 }
146
147 $this->timeenrolled = $timeenrolled;
148 }
149
150 $this->_save();
151 }
152
153 /**
154 * Mark this user as inprogress in this course
155 *
156 * If the user is already marked as inprogress,
157 * the time will not be changed
158 *
159 * @access public
160 * @param integer $timestarted Time started (optional)
161 * @return void
162 */
163 public function mark_inprogress($timestarted = null) {
164
165 $timenow = time();
166
167 // Set reaggregate flag
168 $this->reaggregate = $timenow;
169
170 if (!$this->timestarted) {
171
172 if (!$timestarted) {
173 $timestarted = $timenow;
174 }
175
176 $this->timestarted = $timestarted;
177 }
178
179 $this->_save();
180 }
181
182 /**
183 * Mark this user complete in this course
184 *
185 * This generally happens when the required completion criteria
186 * in the course are complete.
187 *
188 * @access public
189 * @param integer $timecomplete Time completed (optional)
190 * @return void
191 */
192 public function mark_complete($timecomplete = null) {
193
194 // Never change a completion time
195 if ($this->timecompleted) {
196 return;
197 }
198
199 // Use current time if nothing supplied
200 if (!$timecomplete) {
201 $timecomplete = time();
202 }
203
204 // Set time complete
205 $this->timecompleted = $timecomplete;
206
207 // Save record
208 $this->_save();
209 }
210
211 /**
212 * Save course completion status
213 *
214 * This method creates a course_completions record if none exists
215 * @access public
216 * @return void
217 */
218 private function _save() {
219
220 global $DB;
221
89482538
AB
222 if ($this->timeenrolled === null) {
223 $this->timeenrolled = 0;
2be4d090
MD
224 }
225
226 // Save record
227 if ($this->id) {
228 $this->update();
229 } else {
230 // Make sure reaggregate field is not null
231 if (!$this->reaggregate) {
232 $this->reaggregate = 0;
233 }
234
3c63deb9
AB
235 // Make sure timestarted is not null
236 if (!$this->timestarted) {
237 $this->timestarted = 0;
238 }
239
2be4d090
MD
240 $this->insert();
241 }
242 }
243}