803dd94750c284adfd261a7eea1fd71acd14980c
[moodle.git] / lib / completion / completion_criteria_activity.php
1 <?php
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/>.
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  */
26 class completion_criteria_activity extends completion_criteria {
28     /**
29      * Criteria type constant
30      * @var int
31      */
32     public $criteriatype = COMPLETION_CRITERIA_TYPE_ACTIVITY;
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     }
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);
56         if ($this->id) {
57             $mform->setDefault('criteria_activity['.$data->id.']', 1);
58         }
59     }
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;
70         if (!empty($data->criteria_activity) && is_array($data->criteria_activity)) {
72             $this->course = $data->id;
74             foreach (array_keys($data->criteria_activity) as $activity) {
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     }
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;
95         if (!is_array($types)) {
96             global $DB;
97             $types = $DB->get_records('modules');
98         }
100         return $types[$type]->name;
101     }
103     /**
104      * Get module instance
105      * @access  public
106      * @return  object|false
107      */
108     public function get_mod_instance() {
109         global $DB;
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     }
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;
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);
139         $data = $info->get_data($cm, false, $completion->userid);
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             }
147             return true;
148         }
150         return false;
151     }
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     }
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));
172         return shorten_text(urldecode($activity->name));
173     }
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     }
184     /**
185      * Find user's who have completed this criteria
186      * @access  public
187      * @return  void
188      */
189     public function cron() {
190         global $DB;
192         // Get all users who meet this criteria
193         $sql = '
194             SELECT DISTINCT
195                 c.id AS course,
196                 cr.timeend AS date,
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         ';
230         // Loop through completions, and mark as complete
231         $rs = $DB->get_recordset_sql($sql);
232         foreach ($rs as $record) {
234             $completion = new completion_criteria_completion((array)$record);
235             $completion->mark_complete($record->timecompleted);
236         }
237         $rs->close();
238     }
240     /**
241      * Return criteria progress details for display in reports
242      * @access  public
243      * @param   object  $completion     The user's completion record
244      * @return  array
245      */
246     public function get_details($completion) {
247         global $DB, $CFG;
249         // Get completion info
250         $course = new stdClass();
251         $course->id = $completion->course;
252         $info = new completion_info($course);
254         $module = $DB->get_record('course_modules', array('id' => $this->moduleinstance));
255         $data = $info->get_data($module, false, $completion->userid);
257         $activity = $DB->get_record($this->module, array('id' => $module->instance));
259         $details = array();
260         $details['type'] = $this->get_title();
261         $details['criteria'] = '<a href="'.$CFG->wwwroot.'/mod/'.$this->module.'/view.php?id='.$this->moduleinstance.'">'.$activity->name.'</a>';
263         // Build requirements
264         $details['requirement'] = array();
266         if ($module->completion == 1) {
267             $details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
268         } elseif ($module->completion == 2) {
269             if ($module->completionview) {
270                 $details['requirement'][] = get_string('viewingactivity', 'completion', $this->module);
271             }
273             if ($module->completiongradeitemnumber) {
274                 $details['requirement'][] = get_string('achievinggrade', 'completion');
275             }
276         }
278         $details['requirement'] = implode($details['requirement'], ', ');
280         $details['status'] = '';
282         return $details;
283     }