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. 13 // 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/>. 16 17 /** 18 * This file contains the course completion badge award criteria type class 19 * 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> 25 */ 26 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'); 31 32 /** 33 * Badge award criteria -- award on course completion 34 * 35 */ 36 class award_criteria_course extends award_criteria { 37 38 /* @var int Criteria [BADGE_CRITERIA_TYPE_COURSE] */ 39 public $criteriatype = BADGE_CRITERIA_TYPE_COURSE; 40 41 private $courseid; 42 private $course; 43 44 public $required_param = 'course'; 45 public $optional_params = array('grade', 'bydate'); 46 47 public function __construct($record) { 48 global $DB; 49 parent::__construct($record); 50 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); 54 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); 58 } 59 $this->courseid = $this->course->id; 60 } 61 62 /** 63 * Add appropriate form elements to the criteria form 64 * 65 * @param moodleform $mform Moodle forms object 66 * @param stdClass $data details of various modules 67 */ 68 public function config_form_criteria($data) { 69 global $OUTPUT; 70 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')); 75 76 echo $OUTPUT->box_start(); 77 if (!$data->is_locked() && !$data->is_active()) { 78 echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header')); 79 } 80 echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help'); 81 82 if (!empty($this->description)) { 83 echo $OUTPUT->box( 84 format_text($this->description, $this->descriptionformat, 85 array('context' => context_course::instance($this->courseid)) 86 ), 87 'criteria-description' 88 ); 89 } 90 91 if (!empty($this->params)) { 92 echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges') . $this->get_details(), array('clearfix')); 93 } 94 echo $OUTPUT->box_end(); 95 } 96 97 /** 98 * Get criteria details for displaying to users 99 * 100 * @return string 101 */ 102 public function get_details($short = '') { 103 global $DB, $OUTPUT; 104 $param = reset($this->params); 105 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'))); 114 } 115 if (isset($param['grade'])) { 116 $str .= get_string('criteria_descr_grade', 'badges', $param['grade']); 117 } 118 } 119 return $str; 120 } 121 122 /** 123 * Add appropriate new criteria options to the form 124 * 125 */ 126 public function get_options(&$mform) { 127 global $DB; 128 $param = array(); 129 130 if ($this->id !== 0) { 131 $param = reset($this->params); 132 } else { 133 $param['course'] = $mform->getElementValue('course'); 134 $mform->removeElement('course'); 135 } 136 $course = $DB->get_record('course', array('id' => $param['course'])); 137 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); 151 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'); 155 156 // Set existing values. 157 if (isset($param['bydate'])) { 158 $mform->setDefault('bydate_' . $param['course'], $param['bydate']); 159 } 160 161 if (isset($param['grade'])) { 162 $mform->setDefault('grade_' . $param['course'], $param['grade']); 163 } 164 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); 170 171 $none = false; 172 $message = ''; 173 } 174 return array($none, $message); 175 } 176 177 /** 178 * Review this criteria and decide if it has been completed 179 * 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. 183 * 184 * @return bool Whether criteria is complete 185 */ 186 public function review($userid, $filtered = false) { 187 $course = $this->course; 188 189 if ($this->course->startdate > time()) { 190 return false; 191 } 192 193 $info = new completion_info($course); 194 195 foreach ($this->params as $param) { 196 $check_grade = true; 197 $check_date = true; 198 199 if (isset($param['grade'])) { 200 $grade = grade_get_course_grade($userid, $course->id); 201 $check_grade = ($grade->grade >= $param['grade']); 202 } 203 204 if (!$filtered && isset($param['bydate'])) { 205 $cparams = array( 206 'userid' => $userid, 207 'course' => $course->id, 208 ); 209 $completion = new completion_completion($cparams); 210 $date = $completion->timecompleted; 211 $check_date = ($date <= $param['bydate']); 212 } 213 214 if ($info->is_course_complete($userid) && $check_grade && $check_date) { 215 return true; 216 } 217 } 218 219 return false; 220 } 221 222 /** 223 * Returns array with sql code and parameters returning all ids 224 * of users who meet this particular criterion. 225 * 226 * @return array list($join, $where, $params) 227 */ 228 public function get_completed_criteria_sql() { 229 // We have only one criterion here, so taking the first one. 230 $coursecriteria = reset($this->params); 231 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; 235 236 // Add by date parameter. 237 if (isset($param['bydate'])) { 238 $where .= ' AND cc.timecompleted <= :completebydate'; 239 $params['completebydate'] = $coursecriteria['bydate']; 240 } 241 242 return array($join, $where, $params); 243 } 244 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body