Merge branch 'MDL-64784' of https://github.com/paulholden/moodle
[moodle.git] / completion / completion_completion.php
CommitLineData
2be4d090 1<?php
2be4d090
MD
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
2be4d090
MD
17/**
18 * Course completion status for a particular user/course
19 *
836375ec
SH
20 * @package core_completion
21 * @category completion
2be4d090 22 * @copyright 2009 Catalyst IT Ltd
836375ec
SH
23 * @author Aaron Barnes <aaronb@catalyst.net.nz>
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2be4d090 25 */
2be4d090 26
836375ec 27defined('MOODLE_INTERNAL') || die();
75342343 28require_once($CFG->dirroot.'/completion/data_object.php');
2be4d090
MD
29
30/**
31 * Course completion status for a particular user/course
836375ec
SH
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
2be4d090
MD
38 */
39class completion_completion extends data_object {
40
95dd54ee 41 /* @var string $table Database table name that stores completion information */
2be4d090
MD
42 public $table = 'course_completions';
43
95dd54ee 44 /* @var array $required_fields Array of required table fields, must start with 'id'. */
46eca1f7 45 public $required_fields = array('id', 'userid', 'course',
2be4d090
MD
46 'timeenrolled', 'timestarted', 'timecompleted', 'reaggregate');
47
95dd54ee 48 /* @var int $userid User ID */
2be4d090
MD
49 public $userid;
50
95dd54ee 51 /* @var int $course Course ID */
2be4d090
MD
52 public $course;
53
f55ff38a 54 /* @var int Time of course enrolment {@link completion_completion::mark_enrolled()} */
2be4d090
MD
55 public $timeenrolled;
56
57 /**
f55ff38a 58 * Time the user started their course completion {@link completion_completion::mark_inprogress()}
836375ec 59 * @var int
2be4d090
MD
60 */
61 public $timestarted;
62
f55ff38a 63 /* @var int Timestamp of course completion {@link completion_completion::mark_complete()} */
2be4d090
MD
64 public $timecompleted;
65
95dd54ee 66 /* @var int Flag to trigger cron aggregation (timestamp) */
2be4d090
MD
67 public $reaggregate;
68
69
70 /**
71 * Finds and returns a data_object instance based on params.
95dd54ee 72 *
836375ec
SH
73 * @param array $params associative arrays varname = >value
74 * @return data_object instance of data_object or false if none found.
2be4d090
MD
75 */
76 public static function fetch($params) {
ddce4f4b
DW
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;
2be4d090
MD
87 }
88
89 /**
90 * Return status of this completion
836375ec 91 *
95dd54ee 92 * @return bool
2be4d090
MD
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 *
836375ec 103 * @param integer $timeenrolled Time enrolled (optional)
2be4d090
MD
104 */
105 public function mark_enrolled($timeenrolled = null) {
106
89482538 107 if ($this->timeenrolled === null) {
2be4d090 108
89482538 109 if ($timeenrolled === null) {
2be4d090
MD
110 $timeenrolled = time();
111 }
112
113 $this->timeenrolled = $timeenrolled;
114 }
115
dbfcf440 116 return $this->_save();
2be4d090
MD
117 }
118
119 /**
120 * Mark this user as inprogress in this course
121 *
836375ec 122 * If the user is already marked as inprogress, the time will not be changed
2be4d090 123 *
836375ec 124 * @param integer $timestarted Time started (optional)
2be4d090
MD
125 */
126 public function mark_inprogress($timestarted = null) {
127
128 $timenow = time();
129
130 // Set reaggregate flag
131 $this->reaggregate = $timenow;
132
133 if (!$this->timestarted) {
134
135 if (!$timestarted) {
136 $timestarted = $timenow;
137 }
138
139 $this->timestarted = $timestarted;
140 }
141
dbfcf440 142 return $this->_save();
2be4d090
MD
143 }
144
145 /**
146 * Mark this user complete in this course
147 *
148 * This generally happens when the required completion criteria
149 * in the course are complete.
150 *
836375ec
SH
151 * @param integer $timecomplete Time completed (optional)
152 * @return void
2be4d090
MD
153 */
154 public function mark_complete($timecomplete = null) {
06f8ea7b 155 global $USER;
2be4d090 156
06f8ea7b 157 // Never change a completion time.
2be4d090
MD
158 if ($this->timecompleted) {
159 return;
160 }
161
06f8ea7b 162 // Use current time if nothing supplied.
2be4d090
MD
163 if (!$timecomplete) {
164 $timecomplete = time();
165 }
166
06f8ea7b 167 // Set time complete.
2be4d090
MD
168 $this->timecompleted = $timecomplete;
169
06f8ea7b 170 // Save record.
66b23db4 171 if ($result = $this->_save()) {
06f8ea7b 172 $data = $this->get_record_data();
8b233bda 173 \core\event\course_completed::create_from_completion($data)->trigger();
66b23db4
AB
174 }
175
176 return $result;
2be4d090
MD
177 }
178
179 /**
180 * Save course completion status
181 *
182 * This method creates a course_completions record if none exists
dbfcf440
AB
183 * @access private
184 * @return bool
2be4d090
MD
185 */
186 private function _save() {
926f5143 187 if ($this->timeenrolled === null) {
89482538 188 $this->timeenrolled = 0;
2be4d090
MD
189 }
190
ddce4f4b 191 $result = false;
2be4d090
MD
192 // Save record
193 if ($this->id) {
ddce4f4b 194 $result = $this->update();
2be4d090
MD
195 } else {
196 // Make sure reaggregate field is not null
197 if (!$this->reaggregate) {
198 $this->reaggregate = 0;
199 }
200
836375ec
SH
201 // Make sure timestarted is not null
202 if (!$this->timestarted) {
dbfcf440 203 $this->timestarted = 0;
836375ec 204 }
dbfcf440 205
ddce4f4b
DW
206 $result = $this->insert();
207 }
208
209 if ($result) {
210 // Update the cached record.
211 $cache = cache::make('core', 'coursecompletion');
212 $data = $this->get_record_data();
213 $key = $data->userid . '_' . $data->course;
214 $cache->set($key, ['value' => $data]);
2be4d090 215 }
ddce4f4b
DW
216
217 return $result;
2be4d090 218 }
95dd54ee 219}