Merge branch 'MDL-62663' of https://github.com/andrewhancox/moodle
[moodle.git] / badges / criteria / award_criteria_course.php
blob9f5b41a00227d0f20fed1e59f8a2939d2fc9556f
1 <?php
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.
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/>.
17 /**
18 * This file contains the course completion badge award criteria type class
20 * @package core
21 * @subpackage badges
22 * @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @author Yuliya Bozhko <yuliya.bozhko@totaralms.com>
27 defined('MOODLE_INTERNAL') || die();
28 require_once($CFG->libdir . '/completionlib.php');
29 require_once($CFG->dirroot . '/grade/querylib.php');
30 require_once($CFG->libdir . '/gradelib.php');
32 /**
33 * Badge award criteria -- award on course completion
36 class award_criteria_course extends award_criteria {
38 /* @var int Criteria [BADGE_CRITERIA_TYPE_COURSE] */
39 public $criteriatype = BADGE_CRITERIA_TYPE_COURSE;
41 private $courseid;
42 private $course;
44 public $required_param = 'course';
45 public $optional_params = array('grade', 'bydate');
47 public function __construct($record) {
48 global $DB;
49 parent::__construct($record);
51 $this->course = $DB->get_record_sql('SELECT c.id, c.enablecompletion, c.cacherev, c.startdate
52 FROM {badge} b LEFT JOIN {course} c ON b.courseid = c.id
53 WHERE b.id = :badgeid ', array('badgeid' => $this->badgeid), MUST_EXIST);
55 // If the course doesn't exist but we're sure the badge does (thanks to the LEFT JOIN), then use the site as the course.
56 if (empty($this->course->id)) {
57 $this->course = get_course(SITEID);
59 $this->courseid = $this->course->id;
62 /**
63 * Add appropriate form elements to the criteria form
65 * @param moodleform $mform Moodle forms object
66 * @param stdClass $data details of various modules
68 public function config_form_criteria($data) {
69 global $OUTPUT;
71 $editurl = new moodle_url('/badges/criteria_settings.php', array('badgeid' => $this->badgeid, 'edit' => true, 'type' => $this->criteriatype, 'crit' => $this->id));
72 $deleteurl = new moodle_url('/badges/criteria_action.php', array('badgeid' => $this->badgeid, 'delete' => true, 'type' => $this->criteriatype));
73 $editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null, array('class' => 'criteria-action'));
74 $deleteaction = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', get_string('delete')), null, array('class' => 'criteria-action'));
76 echo $OUTPUT->box_start();
77 if (!$data->is_locked() && !$data->is_active()) {
78 echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header'));
80 echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
82 if (!empty($this->description)) {
83 echo $OUTPUT->box(
84 format_text($this->description, $this->descriptionformat,
85 array('context' => context_course::instance($this->courseid))
87 'criteria-description'
91 if (!empty($this->params)) {
92 echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges') . $this->get_details(), array('clearfix'));
94 echo $OUTPUT->box_end();
97 /**
98 * Get criteria details for displaying to users
100 * @return string
102 public function get_details($short = '') {
103 global $DB, $OUTPUT;
104 $param = reset($this->params);
106 $course = $DB->get_record('course', array('id' => $param['course']));
107 if (!$course) {
108 $str = $OUTPUT->error_text(get_string('error:nosuchcourse', 'badges'));
109 } else {
110 $options = array('context' => context_course::instance($course->id));
111 $str = html_writer::tag('b', '"' . format_string($course->fullname, true, $options) . '"');
112 if (isset($param['bydate'])) {
113 $str .= get_string('criteria_descr_bydate', 'badges', userdate($param['bydate'], get_string('strftimedate', 'core_langconfig')));
115 if (isset($param['grade'])) {
116 $str .= get_string('criteria_descr_grade', 'badges', $param['grade']);
119 return $str;
123 * Add appropriate new criteria options to the form
126 public function get_options(&$mform) {
127 global $DB;
128 $param = array();
130 if ($this->id !== 0) {
131 $param = reset($this->params);
132 } else {
133 $param['course'] = $mform->getElementValue('course');
134 $mform->removeElement('course');
136 $course = $DB->get_record('course', array('id' => $param['course']));
138 if (!($course->enablecompletion == COMPLETION_ENABLED)) {
139 $none = true;
140 $message = get_string('completionnotenabled', 'badges');
141 } else {
142 $mform->addElement('header', 'criteria_course', $this->get_title());
143 $mform->addHelpButton('criteria_course', 'criteria_' . $this->criteriatype, 'badges');
144 $parameter = array();
145 $parameter[] =& $mform->createElement('static', 'mgrade_', null, get_string('mingrade', 'badges'));
146 $parameter[] =& $mform->createElement('text', 'grade_' . $param['course'], '', array('size' => '5'));
147 $parameter[] =& $mform->createElement('static', 'complby_' . $param['course'], null, get_string('bydate', 'badges'));
148 $parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['course'], '', array('optional' => true));
149 $mform->setType('grade_' . $param['course'], PARAM_INT);
150 $mform->addGroup($parameter, 'param_' . $param['course'], '', array(' '), false);
152 $mform->disabledIf('bydate_' . $param['course'] . '[day]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
153 $mform->disabledIf('bydate_' . $param['course'] . '[month]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
154 $mform->disabledIf('bydate_' . $param['course'] . '[year]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
156 // Set existing values.
157 if (isset($param['bydate'])) {
158 $mform->setDefault('bydate_' . $param['course'], $param['bydate']);
161 if (isset($param['grade'])) {
162 $mform->setDefault('grade_' . $param['course'], $param['grade']);
165 // Add hidden elements.
166 $mform->addElement('hidden', 'course_' . $course->id, $course->id);
167 $mform->setType('course_' . $course->id, PARAM_INT);
168 $mform->addElement('hidden', 'agg', BADGE_CRITERIA_AGGREGATION_ALL);
169 $mform->setType('agg', PARAM_INT);
171 $none = false;
172 $message = '';
174 return array($none, $message);
178 * Review this criteria and decide if it has been completed
180 * @param int $userid User whose criteria completion needs to be reviewed.
181 * @param bool $filtered An additional parameter indicating that user list
182 * has been reduced and some expensive checks can be skipped.
184 * @return bool Whether criteria is complete
186 public function review($userid, $filtered = false) {
187 $course = $this->course;
189 if ($this->course->startdate > time()) {
190 return false;
193 $info = new completion_info($course);
195 foreach ($this->params as $param) {
196 $check_grade = true;
197 $check_date = true;
199 if (isset($param['grade'])) {
200 $grade = grade_get_course_grade($userid, $course->id);
201 $check_grade = ($grade->grade >= $param['grade']);
204 if (!$filtered && isset($param['bydate'])) {
205 $cparams = array(
206 'userid' => $userid,
207 'course' => $course->id,
209 $completion = new completion_completion($cparams);
210 $date = $completion->timecompleted;
211 $check_date = ($date <= $param['bydate']);
214 if ($info->is_course_complete($userid) && $check_grade && $check_date) {
215 return true;
219 return false;
223 * Returns array with sql code and parameters returning all ids
224 * of users who meet this particular criterion.
226 * @return array list($join, $where, $params)
228 public function get_completed_criteria_sql() {
229 // We have only one criterion here, so taking the first one.
230 $coursecriteria = reset($this->params);
232 $join = " LEFT JOIN {course_completions} cc ON cc.userid = u.id AND cc.timecompleted > 0";
233 $where = ' AND cc.course = :courseid ';
234 $params['courseid'] = $this->courseid;
236 // Add by date parameter.
237 if (isset($param['bydate'])) {
238 $where .= ' AND cc.timecompleted <= :completebydate';
239 $params['completebydate'] = $coursecriteria['bydate'];
242 return array($join, $where, $params);