2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * This file contains the course completion badge award criteria type class
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');
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
;
44 public $required_param = 'course';
45 public $optional_params = array('grade', 'bydate');
47 public function __construct($record) {
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
;
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) {
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
)) {
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();
98 * Get criteria details for displaying to users
102 public function get_details($short = '') {
104 $param = reset($this->params
);
106 $course = $DB->get_record('course', array('id' => $param['course']));
108 $str = $OUTPUT->error_text(get_string('error:nosuchcourse', 'badges'));
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']);
123 * Add appropriate new criteria options to the form
126 public function get_options(&$mform) {
130 if ($this->id
!== 0) {
131 $param = reset($this->params
);
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
)) {
140 $message = get_string('completionnotenabled', 'badges');
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
);
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()) {
193 $info = new completion_info($course);
195 foreach ($this->params
as $param) {
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'])) {
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) {
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);