MDL-42870 completion: show failed activities as incompleted
[moodle.git] / completion / criteria / 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
836375ec
SH
18/**
19 * This file contains the activity completion criteria type class and any
20 * supporting functions it may require.
21 *
22 * @package core_completion
23 * @category completion
24 * @copyright 2009 Catalyst IT Ltd
25 * @author Aaron Barnes <aaronb@catalyst.net.nz>
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
28
29defined('MOODLE_INTERNAL') || die();
30
2be4d090
MD
31/**
32 * Course completion critieria - completion on activity completion
33 *
836375ec
SH
34 * @package core_completion
35 * @category completion
2be4d090 36 * @copyright 2009 Catalyst IT Ltd
836375ec
SH
37 * @author Aaron Barnes <aaronb@catalyst.net.nz>
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2be4d090
MD
39 */
40class completion_criteria_activity extends completion_criteria {
41
95dd54ee 42 /* @var int Criteria [COMPLETION_CRITERIA_TYPE_ACTIVITY] */
2be4d090
MD
43 public $criteriatype = COMPLETION_CRITERIA_TYPE_ACTIVITY;
44
45 /**
46 * Finds and returns a data_object instance based on params.
2be4d090
MD
47 *
48 * @param array $params associative arrays varname=>value
836375ec 49 * @return completion_criteria_activity data_object instance or false if none found.
2be4d090
MD
50 */
51 public static function fetch($params) {
52 $params['criteriatype'] = COMPLETION_CRITERIA_TYPE_ACTIVITY;
53 return self::fetch_helper('course_completion_criteria', __CLASS__, $params);
54 }
55
56 /**
57 * Add appropriate form elements to the critieria form
95dd54ee 58 *
836375ec 59 * @param moodleform $mform Moodle forms object
95dd54ee 60 * @param stdClass $data details of various modules
2be4d090
MD
61 */
62 public function config_form_display(&$mform, $data = null) {
63 $mform->addElement('checkbox', 'criteria_activity['.$data->id.']', ucfirst(self::get_mod_name($data->module)).' - '.$data->name);
64
65 if ($this->id) {
66 $mform->setDefault('criteria_activity['.$data->id.']', 1);
67 }
68 }
69
70 /**
71 * Update the criteria information stored in the database
95dd54ee 72 *
836375ec 73 * @param stdClass $data Form data
2be4d090
MD
74 */
75 public function update_config(&$data) {
76 global $DB;
77
78 if (!empty($data->criteria_activity) && is_array($data->criteria_activity)) {
79
80 $this->course = $data->id;
81
82 foreach (array_keys($data->criteria_activity) as $activity) {
83
84 $module = $DB->get_record('course_modules', array('id' => $activity));
85 $this->module = self::get_mod_name($module->module);
86 $this->moduleinstance = $activity;
87 $this->id = NULL;
88 $this->insert();
89 }
90 }
91 }
92
93 /**
94 * Get module instance module type
95dd54ee 95 *
836375ec
SH
96 * @param int $type Module type id
97 * @return string
2be4d090
MD
98 */
99 public static function get_mod_name($type) {
100 static $types;
101
102 if (!is_array($types)) {
103 global $DB;
104 $types = $DB->get_records('modules');
105 }
106
107 return $types[$type]->name;
108 }
109
110 /**
836375ec
SH
111 * Gets the module instance from the database and returns it.
112 * If no module instance exists this function returns false.
113 *
95dd54ee 114 * @return stdClass|bool
2be4d090
MD
115 */
116 public function get_mod_instance() {
117 global $DB;
118
119 return $DB->get_record_sql(
120 "
121 SELECT
122 m.*
123 FROM
124 {{$this->module}} m
125 INNER JOIN
126 {course_modules} cm
127 ON cm.id = {$this->moduleinstance}
128 AND m.id = cm.instance
129 "
130 );
131 }
132
133 /**
134 * Review this criteria and decide if the user has completed
836375ec
SH
135 *
136 * @param completion_completion $completion The user's completion record
95dd54ee
AA
137 * @param bool $mark Optionally set false to not save changes to database
138 * @return bool
2be4d090
MD
139 */
140 public function review($completion, $mark = true) {
141 global $DB;
142
143 $course = $DB->get_record('course', array('id' => $completion->course));
144 $cm = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
145 $info = new completion_info($course);
146
147 $data = $info->get_data($cm, false, $completion->userid);
148
149 // If the activity is complete
150 if (in_array($data->completionstate, array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS))) {
151 if ($mark) {
152 $completion->mark_complete();
153 }
154
155 return true;
156 }
157
158 return false;
159 }
160
161 /**
162 * Return criteria title for display in reports
836375ec
SH
163 *
164 * @return string
2be4d090
MD
165 */
166 public function get_title() {
167 return get_string('activitiescompleted', 'completion');
168 }
169
170 /**
171 * Return a more detailed criteria title for display in reports
836375ec 172 *
2be4d090
MD
173 * @return string
174 */
175 public function get_title_detailed() {
176 global $DB;
177 $module = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
178 $activity = $DB->get_record($this->module, array('id' => $module->instance));
179
180 return shorten_text(urldecode($activity->name));
181 }
182
183 /**
184 * Return criteria type title for display in reports
836375ec 185 *
2be4d090
MD
186 * @return string
187 */
188 public function get_type_title() {
189 return get_string('activities', 'completion');
190 }
191
192 /**
95dd54ee 193 * Find users who have completed this criteria and mark them accordingly
2be4d090
MD
194 */
195 public function cron() {
196 global $DB;
197
198 // Get all users who meet this criteria
199 $sql = '
200 SELECT DISTINCT
201 c.id AS course,
2be4d090
MD
202 cr.id AS criteriaid,
203 ra.userid AS userid,
204 mc.timemodified AS timecompleted
205 FROM
206 {course_completion_criteria} cr
207 INNER JOIN
208 {course} c
209 ON cr.course = c.id
210 INNER JOIN
211 {context} con
212 ON con.instanceid = c.id
213 INNER JOIN
214 {role_assignments} ra
215 ON ra.contextid = con.id
216 INNER JOIN
217 {course_modules_completion} mc
218 ON mc.coursemoduleid = cr.moduleinstance
219 AND mc.userid = ra.userid
220 LEFT JOIN
221 {course_completion_crit_compl} cc
222 ON cc.criteriaid = cr.id
223 AND cc.userid = ra.userid
224 WHERE
225 cr.criteriatype = '.COMPLETION_CRITERIA_TYPE_ACTIVITY.'
226 AND con.contextlevel = '.CONTEXT_COURSE.'
227 AND c.enablecompletion = 1
228 AND cc.id IS NULL
229 AND (
230 mc.completionstate = '.COMPLETION_COMPLETE.'
231 OR mc.completionstate = '.COMPLETION_COMPLETE_PASS.'
232 )
233 ';
234
235 // Loop through completions, and mark as complete
419178d7
EL
236 $rs = $DB->get_recordset_sql($sql);
237 foreach ($rs as $record) {
28e0c239 238 $completion = new completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY);
419178d7 239 $completion->mark_complete($record->timecompleted);
2be4d090 240 }
419178d7 241 $rs->close();
2be4d090
MD
242 }
243
244 /**
245 * Return criteria progress details for display in reports
836375ec
SH
246 *
247 * @param completion_completion $completion The user's completion record
248 * @return array An array with the following keys:
249 * type, criteria, requirement, status
2be4d090
MD
250 */
251 public function get_details($completion) {
252 global $DB, $CFG;
253
254 // Get completion info
365a5941 255 $course = new stdClass();
2be4d090
MD
256 $course->id = $completion->course;
257 $info = new completion_info($course);
258
259 $module = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
260 $data = $info->get_data($module, false, $completion->userid);
261
262 $activity = $DB->get_record($this->module, array('id' => $module->instance));
263
264 $details = array();
265 $details['type'] = $this->get_title();
266 $details['criteria'] = '<a href="'.$CFG->wwwroot.'/mod/'.$this->module.'/view.php?id='.$this->moduleinstance.'">'.$activity->name.'</a>';
267
268 // Build requirements
269 $details['requirement'] = array();
270
271 if ($module->completion == 1) {
272 $details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
273 } elseif ($module->completion == 2) {
274 if ($module->completionview) {
275 $details['requirement'][] = get_string('viewingactivity', 'completion', $this->module);
276 }
277
47567108 278 if (!is_null($module->completiongradeitemnumber)) {
2be4d090
MD
279 $details['requirement'][] = get_string('achievinggrade', 'completion');
280 }
281 }
282
283 $details['requirement'] = implode($details['requirement'], ', ');
284
285 $details['status'] = '';
286
287 return $details;
288 }
95dd54ee 289}