MDL-25708 recordsets - fix events/grade/group/moodle libs
[moodle.git] / lib / completion / completion_criteria_activity.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 * Course completion critieria - completion on activity completion
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 */
26class completion_criteria_activity extends completion_criteria {
27
28 /**
29 * Criteria type constant
30 * @var int
31 */
32 public $criteriatype = COMPLETION_CRITERIA_TYPE_ACTIVITY;
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_ACTIVITY;
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 $mform->addElement('checkbox', 'criteria_activity['.$data->id.']', ucfirst(self::get_mod_name($data->module)).' - '.$data->name);
55
56 if ($this->id) {
57 $mform->setDefault('criteria_activity['.$data->id.']', 1);
58 }
59 }
60
61 /**
62 * Update the criteria information stored in the database
63 * @access public
64 * @param array $data Form data
65 * @return void
66 */
67 public function update_config(&$data) {
68 global $DB;
69
70 if (!empty($data->criteria_activity) && is_array($data->criteria_activity)) {
71
72 $this->course = $data->id;
73
74 foreach (array_keys($data->criteria_activity) as $activity) {
75
76 $module = $DB->get_record('course_modules', array('id' => $activity));
77 $this->module = self::get_mod_name($module->module);
78 $this->moduleinstance = $activity;
79 $this->id = NULL;
80 $this->insert();
81 }
82 }
83 }
84
85 /**
86 * Get module instance module type
87 * @static
88 * @access public
89 * @param int $type Module type id
90 * @return string
91 */
92 public static function get_mod_name($type) {
93 static $types;
94
95 if (!is_array($types)) {
96 global $DB;
97 $types = $DB->get_records('modules');
98 }
99
100 return $types[$type]->name;
101 }
102
103 /**
104 * Get module instance
105 * @access public
106 * @return object|false
107 */
108 public function get_mod_instance() {
109 global $DB;
110
111 return $DB->get_record_sql(
112 "
113 SELECT
114 m.*
115 FROM
116 {{$this->module}} m
117 INNER JOIN
118 {course_modules} cm
119 ON cm.id = {$this->moduleinstance}
120 AND m.id = cm.instance
121 "
122 );
123 }
124
125 /**
126 * Review this criteria and decide if the user has completed
127 * @access public
128 * @param object $completion The user's completion record
129 * @param boolean $mark Optionally set false to not save changes to database
130 * @return boolean
131 */
132 public function review($completion, $mark = true) {
133 global $DB;
134
135 $course = $DB->get_record('course', array('id' => $completion->course));
136 $cm = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
137 $info = new completion_info($course);
138
139 $data = $info->get_data($cm, false, $completion->userid);
140
141 // If the activity is complete
142 if (in_array($data->completionstate, array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS))) {
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 * @access public
156 * @return string
157 */
158 public function get_title() {
159 return get_string('activitiescompleted', 'completion');
160 }
161
162 /**
163 * Return a more detailed criteria title for display in reports
164 * @access public
165 * @return string
166 */
167 public function get_title_detailed() {
168 global $DB;
169 $module = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
170 $activity = $DB->get_record($this->module, array('id' => $module->instance));
171
172 return shorten_text(urldecode($activity->name));
173 }
174
175 /**
176 * Return criteria type title for display in reports
177 * @access public
178 * @return string
179 */
180 public function get_type_title() {
181 return get_string('activities', 'completion');
182 }
183
184 /**
185 * Find user's who have completed this criteria
186 * @access public
187 * @return void
188 */
189 public function cron() {
190 global $DB;
191
192 // Get all users who meet this criteria
193 $sql = '
194 SELECT DISTINCT
195 c.id AS course,
fe09ccba 196 cr.timeend AS date,
2be4d090
MD
197 cr.id AS criteriaid,
198 ra.userid AS userid,
199 mc.timemodified AS timecompleted
200 FROM
201 {course_completion_criteria} cr
202 INNER JOIN
203 {course} c
204 ON cr.course = c.id
205 INNER JOIN
206 {context} con
207 ON con.instanceid = c.id
208 INNER JOIN
209 {role_assignments} ra
210 ON ra.contextid = con.id
211 INNER JOIN
212 {course_modules_completion} mc
213 ON mc.coursemoduleid = cr.moduleinstance
214 AND mc.userid = ra.userid
215 LEFT JOIN
216 {course_completion_crit_compl} cc
217 ON cc.criteriaid = cr.id
218 AND cc.userid = ra.userid
219 WHERE
220 cr.criteriatype = '.COMPLETION_CRITERIA_TYPE_ACTIVITY.'
221 AND con.contextlevel = '.CONTEXT_COURSE.'
222 AND c.enablecompletion = 1
223 AND cc.id IS NULL
224 AND (
225 mc.completionstate = '.COMPLETION_COMPLETE.'
226 OR mc.completionstate = '.COMPLETION_COMPLETE_PASS.'
227 )
228 ';
229
230 // Loop through completions, and mark as complete
231 if ($rs = $DB->get_recordset_sql($sql)) {
232 foreach ($rs as $record) {
233
234 $completion = new completion_criteria_completion((array)$record);
235 $completion->mark_complete($record->timecompleted);
236 }
237
238 $rs->close();
239 }
240 }
241
242 /**
243 * Return criteria progress details for display in reports
244 * @access public
245 * @param object $completion The user's completion record
246 * @return array
247 */
248 public function get_details($completion) {
249 global $DB, $CFG;
250
251 // Get completion info
365a5941 252 $course = new stdClass();
2be4d090
MD
253 $course->id = $completion->course;
254 $info = new completion_info($course);
255
256 $module = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
257 $data = $info->get_data($module, false, $completion->userid);
258
259 $activity = $DB->get_record($this->module, array('id' => $module->instance));
260
261 $details = array();
262 $details['type'] = $this->get_title();
263 $details['criteria'] = '<a href="'.$CFG->wwwroot.'/mod/'.$this->module.'/view.php?id='.$this->moduleinstance.'">'.$activity->name.'</a>';
264
265 // Build requirements
266 $details['requirement'] = array();
267
268 if ($module->completion == 1) {
269 $details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
270 } elseif ($module->completion == 2) {
271 if ($module->completionview) {
272 $details['requirement'][] = get_string('viewingactivity', 'completion', $this->module);
273 }
274
275 if ($module->completiongradeitemnumber) {
276 $details['requirement'][] = get_string('achievinggrade', 'completion');
277 }
278 }
279
280 $details['requirement'] = implode($details['requirement'], ', ');
281
282 $details['status'] = '';
283
284 return $details;
285 }
286}