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 courseset 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 ('award_criteria_course.php'); 29 require_once($CFG->libdir . '/completionlib.php'); 30 require_once($CFG->dirroot . '/grade/querylib.php'); 31 require_once($CFG->libdir . '/gradelib.php'); 32 33 /** 34 * Badge award criteria -- award on courseset completion 35 * 36 */ 37 class award_criteria_courseset extends award_criteria { 38 39 /* @var int Criteria [BADGE_CRITERIA_TYPE_COURSESET] */ 40 public $criteriatype = BADGE_CRITERIA_TYPE_COURSESET; 41 42 public $required_param = 'course'; 43 public $optional_params = array('grade', 'bydate'); 44 45 /** 46 * Get criteria details for displaying to users 47 * 48 * @return string 49 */ 50 public function get_details($short = '') { 51 global $DB, $OUTPUT; 52 $output = array(); 53 foreach ($this->params as $p) { 54 $coursename = $DB->get_field('course', 'fullname', array('id' => $p['course'])); 55 if (!$coursename) { 56 $str = $OUTPUT->error_text(get_string('error:nosuchcourse', 'badges')); 57 } else { 58 $str = html_writer::tag('b', '"' . $coursename . '"'); 59 if (isset($p['bydate'])) { 60 $str .= get_string('criteria_descr_bydate', 'badges', userdate($p['bydate'], get_string('strftimedate', 'core_langconfig'))); 61 } 62 if (isset($p['grade'])) { 63 $str .= get_string('criteria_descr_grade', 'badges', $p['grade']); 64 } 65 } 66 $output[] = $str; 67 } 68 69 if ($short) { 70 return implode(', ', $output); 71 } else { 72 return html_writer::alist($output, array(), 'ul'); 73 } 74 } 75 76 public function get_courses(&$mform) { 77 global $DB, $CFG; 78 require_once($CFG->dirroot . '/course/lib.php'); 79 $buttonarray = array(); 80 81 $hasselectablecourses = core_course_category::search_courses(['onlywithcompletion' => true], ['limit' => 1]); 82 if ($hasselectablecourses) { 83 $settings = array('multiple' => 'multiple', 'onlywithcompletion' => 1); 84 $mform->addElement('course', 'courses', get_string('addcourse', 'badges'), $settings); 85 $mform->addRule('courses', get_string('requiredcourse', 'badges'), 'required'); 86 $mform->addHelpButton('courses', 'addcourse', 'badges'); 87 88 $buttonarray[] =& $mform->createElement('submit', 'submitcourse', get_string('addcourse', 'badges')); 89 $buttonarray[] =& $mform->createElement('submit', 'cancel', get_string('cancel')); 90 $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); 91 92 $mform->addElement('hidden', 'addcourse', 'addcourse'); 93 $mform->setType('addcourse', PARAM_TEXT); 94 if ($this->id !== 0) { 95 $selected = array_keys($this->params); 96 $mform->setDefault('courses', $selected); 97 } 98 $mform->setType('agg', PARAM_INT); 99 } else { 100 $mform->addElement('static', 'nocourses', '', get_string('error:nocourses', 'badges')); 101 $buttonarray[] =& $mform->createElement('submit', 'cancel', get_string('continue')); 102 $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); 103 } 104 } 105 106 public function add_courses($params = array()) { 107 global $DB; 108 $t = $DB->start_delegated_transaction(); 109 if ($this->id !== 0) { 110 $critid = $this->id; 111 } else { 112 $fordb = new stdClass(); 113 $fordb->criteriatype = $this->criteriatype; 114 $fordb->method = BADGE_CRITERIA_AGGREGATION_ALL; 115 $fordb->badgeid = $this->badgeid; 116 $critid = $DB->insert_record('badge_criteria', $fordb, true, true); 117 } 118 if ($critid) { 119 foreach ($params as $p) { 120 $newp = new stdClass(); 121 $newp->critid = $critid; 122 $newp->name = 'course_' . $p; 123 $newp->value = $p; 124 if (!$DB->record_exists('badge_criteria_param', array('critid' => $critid, 'name' => $newp->name))) { 125 $DB->insert_record('badge_criteria_param', $newp, false, true); 126 } 127 } 128 } 129 $t->allow_commit(); 130 return $critid; 131 } 132 133 /** 134 * Add appropriate new criteria options to the form 135 * 136 */ 137 public function get_options(&$mform) { 138 global $DB; 139 $none = true; 140 141 $mform->addElement('header', 'first_header', $this->get_title()); 142 $mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges'); 143 144 if ($courses = $DB->get_records('course', array('enablecompletion' => COMPLETION_ENABLED))) { 145 $mform->addElement('submit', 'addcourse', get_string('addcourse', 'badges'), array('class' => 'addcourse')); 146 } 147 148 // In courseset, print out only the ones that were already selected. 149 foreach ($this->params as $p) { 150 if ($course = $DB->get_record('course', array('id' => $p['course']))) { 151 $coursecontext = context_course::instance($course->id); 152 $param = array( 153 'id' => $course->id, 154 'checked' => true, 155 'name' => format_string($course->fullname, true, array('context' => $coursecontext)), 156 'error' => false 157 ); 158 159 if (isset($p['bydate'])) { 160 $param['bydate'] = $p['bydate']; 161 } 162 if (isset($p['grade'])) { 163 $param['grade'] = $p['grade']; 164 } 165 $this->config_options($mform, $param); 166 $none = false; 167 } else { 168 $this->config_options($mform, array('id' => $p['course'], 'checked' => true, 169 'name' => get_string('error:nosuchcourse', 'badges'), 'error' => true)); 170 } 171 } 172 173 // Add aggregation. 174 if (!$none) { 175 $mform->addElement('header', 'aggregation', get_string('method', 'badges')); 176 $agg = array(); 177 $agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodcourseset', 'badges'), 1); 178 $agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodcourseset', 'badges'), 2); 179 $mform->addGroup($agg, 'methodgr', '', array('<br/>'), false); 180 if ($this->id !== 0) { 181 $mform->setDefault('agg', $this->method); 182 } else { 183 $mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY); 184 } 185 } 186 187 return array($none, get_string('noparamstoadd', 'badges')); 188 } 189 190 /** 191 * Review this criteria and decide if it has been completed 192 * 193 * @param int $userid User whose criteria completion needs to be reviewed. 194 * @param bool $filtered An additional parameter indicating that user list 195 * has been reduced and some expensive checks can be skipped. 196 * 197 * @return bool Whether criteria is complete 198 */ 199 public function review($userid, $filtered = false) { 200 foreach ($this->params as $param) { 201 $course = new stdClass(); 202 $course->id = $param['course']; 203 204 $info = new completion_info($course); 205 $check_grade = true; 206 $check_date = true; 207 208 if (isset($param['grade'])) { 209 $grade = grade_get_course_grade($userid, $course->id); 210 $check_grade = ($grade->grade >= $param['grade']); 211 } 212 213 if (!$filtered && isset($param['bydate'])) { 214 $cparams = array( 215 'userid' => $userid, 216 'course' => $course->id, 217 ); 218 $completion = new completion_completion($cparams); 219 $date = $completion->timecompleted; 220 $check_date = ($date <= $param['bydate']); 221 } 222 223 $overall = false; 224 if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) { 225 if ($info->is_course_complete($userid) && $check_grade && $check_date) { 226 $overall = true; 227 continue; 228 } else { 229 return false; 230 } 231 } else { 232 if ($info->is_course_complete($userid) && $check_grade && $check_date) { 233 return true; 234 } else { 235 $overall = false; 236 continue; 237 } 238 } 239 } 240 241 return $overall; 242 } 243 244 /** 245 * Returns array with sql code and parameters returning all ids 246 * of users who meet this particular criterion. 247 * 248 * @return array list($join, $where, $params) 249 */ 250 public function get_completed_criteria_sql() { 251 $join = ''; 252 $where = ''; 253 $params = array(); 254 255 if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) { 256 foreach ($this->params as $param) { 257 $coursedata[] = " cc.course = :completedcourse{$param['course']} "; 258 $params["completedcourse{$param['course']}"] = $param['course']; 259 } 260 if (!empty($coursedata)) { 261 $extraon = implode(' OR ', $coursedata); 262 $join = " JOIN {course_completions} cc ON cc.userid = u.id AND 263 cc.timecompleted > 0 AND ({$extraon})"; 264 } 265 return array($join, $where, $params); 266 } else { 267 foreach ($this->params as $param) { 268 $join .= " LEFT JOIN {course_completions} cc{$param['course']} ON 269 cc{$param['course']}.userid = u.id AND 270 cc{$param['course']}.course = :completedcourse{$param['course']} AND 271 cc{$param['course']}.timecompleted > 0 "; 272 $where .= " AND cc{$param['course']}.course IS NOT NULL "; 273 $params["completedcourse{$param['course']}"] = $param['course']; 274 } 275 return array($join, $where, $params); 276 } 277 } 278 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body