See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 * Class for loading/storing competencies from the DB. 19 * 20 * @package core_competency 21 * @copyright 2015 Damyon Wiese 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace core_competency; 25 defined('MOODLE_INTERNAL') || die(); 26 27 use coding_exception; 28 use stdClass; 29 use lang_string; 30 31 /** 32 * Class for loading/storing course_competencies from the DB. 33 * 34 * @copyright 2015 Damyon Wiese 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class course_competency extends persistent { 38 39 const TABLE = 'competency_coursecomp'; 40 41 /** Course competency ruleoutcome constant. */ 42 const OUTCOME_NONE = 0; 43 /** Course competency ruleoutcome constant. */ 44 const OUTCOME_EVIDENCE = 1; 45 /** Course competency ruleoutcome constant. */ 46 const OUTCOME_RECOMMEND = 2; 47 /** Course competency ruleoutcome constant. */ 48 const OUTCOME_COMPLETE = 3; 49 50 /** 51 * Return the definition of the properties of this model. 52 * 53 * @return array 54 */ 55 protected static function define_properties() { 56 return array( 57 'courseid' => array( 58 'type' => PARAM_INT 59 ), 60 'competencyid' => array( 61 'type' => PARAM_INT 62 ), 63 'sortorder' => array( 64 'type' => PARAM_INT 65 ), 66 'ruleoutcome' => array( 67 'choices' => array(self::OUTCOME_NONE, 68 self::OUTCOME_EVIDENCE, 69 self::OUTCOME_RECOMMEND, 70 self::OUTCOME_COMPLETE 71 ), 72 'default' => self::OUTCOME_EVIDENCE, 73 'type' => PARAM_INT, 74 ), 75 ); 76 } 77 78 /** 79 * Hook to execute before validate. 80 * 81 * @return void 82 */ 83 protected function before_validate() { 84 if (($this->get('id') && $this->get('sortorder') === null) || !$this->get('id')) { 85 $this->set('sortorder', $this->count_records(array('courseid' => $this->get('courseid')))); 86 } 87 } 88 89 /** 90 * Return the courses where both competency and user are. 91 * 92 * A user is considered being in a course when they are enrolled, the enrolment is valid, 93 * the enrolment instance is enabled, and the enrolment plugin is enabled.. 94 * 95 * @param int $competencyid The competency ID. 96 * @param int $userid The user ID. 97 * @return array Indexed by course ID. 98 */ 99 public static function get_courses_with_competency_and_user($competencyid, $userid) { 100 global $CFG, $DB; 101 102 if (!$plugins = explode(',', $CFG->enrol_plugins_enabled)) { 103 return array(); 104 } 105 106 $ctxfields = \context_helper::get_preload_record_columns_sql('ctx'); 107 list($plugins, $params) = $DB->get_in_or_equal($plugins, SQL_PARAMS_NAMED, 'ee'); 108 $params['competencyid'] = $competencyid; 109 $params['userid'] = $userid; 110 $params['enabled'] = ENROL_INSTANCE_ENABLED; 111 $params['active'] = ENROL_USER_ACTIVE; 112 $params['contextlevel'] = CONTEXT_COURSE; 113 114 // Heavily based on enrol_get_shared_courses(). 115 $sql = "SELECT c.*, $ctxfields 116 FROM {course} c 117 JOIN {" . static::TABLE . "} cc 118 ON cc.courseid = c.id 119 AND cc.competencyid = :competencyid 120 JOIN ( 121 SELECT DISTINCT c.id 122 FROM {enrol} e 123 JOIN {user_enrolments} ue 124 ON ue.enrolid = e.id 125 AND ue.status = :active 126 AND ue.userid = :userid 127 JOIN {course} c 128 ON c.id = e.courseid 129 WHERE e.status = :enabled 130 AND e.enrol $plugins 131 ) ec ON ec.id = c.id 132 LEFT JOIN {context} ctx 133 ON ctx.instanceid = c.id 134 AND ctx.contextlevel = :contextlevel 135 ORDER BY c.id"; 136 137 $courses = $DB->get_records_sql($sql, $params); 138 array_map('context_helper::preload_from_record', $courses); 139 return $courses; 140 } 141 142 /** 143 * Return a list of rules. 144 * 145 * @return array Indexed by outcome value. 146 */ 147 public static function get_ruleoutcome_list() { 148 static $list = null; 149 150 if ($list === null) { 151 $list = array( 152 self::OUTCOME_NONE => self::get_ruleoutcome_name(self::OUTCOME_NONE), 153 self::OUTCOME_EVIDENCE => self::get_ruleoutcome_name(self::OUTCOME_EVIDENCE), 154 self::OUTCOME_RECOMMEND => self::get_ruleoutcome_name(self::OUTCOME_RECOMMEND), 155 self::OUTCOME_COMPLETE => self::get_ruleoutcome_name(self::OUTCOME_COMPLETE)); 156 } 157 158 return $list; 159 } 160 161 /** 162 * Human readable rule name. 163 * 164 * @param int $ruleoutcome The value of ruleoutcome. 165 * @return lang_string 166 */ 167 public static function get_ruleoutcome_name($ruleoutcome) { 168 169 switch ($ruleoutcome) { 170 case self::OUTCOME_NONE: 171 $strname = 'none'; 172 break; 173 case self::OUTCOME_EVIDENCE: 174 $strname = 'evidence'; 175 break; 176 case self::OUTCOME_RECOMMEND: 177 $strname = 'recommend'; 178 break; 179 case self::OUTCOME_COMPLETE: 180 $strname = 'complete'; 181 break; 182 default: 183 throw new \moodle_exception('errorcoursecompetencyrule', 'core_competency', '', $ruleoutcome); 184 break; 185 } 186 187 return new lang_string('coursecompetencyoutcome_' . $strname, 'core_competency'); 188 } 189 190 /** 191 * Validate course ID. 192 * 193 * @param int $data The course ID. 194 * @return true|lang_string 195 */ 196 protected function validate_courseid($data) { 197 global $DB; 198 if (!$DB->record_exists('course', array('id' => $data))) { 199 return new lang_string('invalidcourseid', 'error'); 200 } 201 return true; 202 } 203 204 /** 205 * Validate competency ID. 206 * 207 * @param int $data The competency ID. 208 * @return true|lang_string 209 */ 210 protected function validate_competencyid($data) { 211 if (!competency::record_exists($data)) { 212 return new lang_string('invaliddata', 'error'); 213 } 214 return true; 215 } 216 217 /** 218 * Return the course IDs and visible flags that include this competency. 219 * 220 * Only the ids and visible flag are returned, for the full records use list_courses. 221 * 222 * @param int $competencyid The competency id 223 * @return array containing courseid and visible. 224 */ 225 public static function list_courses_min($competencyid) { 226 global $DB; 227 228 $results = $DB->get_records_sql('SELECT course.id as id, course.visible as visible 229 FROM {' . self::TABLE . '} coursecomp 230 JOIN {course} course 231 ON coursecomp.courseid = course.id 232 WHERE coursecomp.competencyid = ? ', array($competencyid)); 233 234 return $results; 235 } 236 237 /** 238 * Return partial course records foreach course that contains this competency. 239 * 240 * @param int $competencyid The competency id 241 * @return array[stdClass] Array of course records containg id, visible, shortname, idnumber, fullname 242 */ 243 public static function list_courses($competencyid) { 244 global $DB; 245 246 $results = $DB->get_records_sql('SELECT course.id, course.visible, course.shortname, course.idnumber, 247 course.fullname, course.summary, course.summaryformat, course.startdate, 248 course.enddate, course.category 249 FROM {course} course 250 JOIN {' . self::TABLE . '} coursecomp 251 ON coursecomp.courseid = course.id 252 WHERE coursecomp.competencyid = ? ', array($competencyid)); 253 254 return $results; 255 } 256 257 /** 258 * Count the competencies in this course. 259 * 260 * @param int $courseid The course id 261 * @return int 262 */ 263 public static function count_competencies($courseid) { 264 global $DB; 265 266 $sql = 'SELECT COUNT(comp.id) 267 FROM {' . self::TABLE . '} coursecomp 268 JOIN {' . competency::TABLE . '} comp 269 ON coursecomp.competencyid = comp.id 270 WHERE coursecomp.courseid = ? '; 271 $params = array($courseid); 272 273 $results = $DB->count_records_sql($sql, $params); 274 275 return $results; 276 } 277 278 /** 279 * List the competencies in this course. 280 * 281 * @param int $courseid The course id 282 * @return competency[] Indexed by competency ID. 283 */ 284 public static function list_competencies($courseid) { 285 global $DB; 286 287 $sql = 'SELECT comp.* 288 FROM {' . competency::TABLE . '} comp 289 JOIN {' . self::TABLE . '} coursecomp 290 ON coursecomp.competencyid = comp.id 291 WHERE coursecomp.courseid = ?'; 292 $params = array($courseid); 293 294 $sql .= ' ORDER BY coursecomp.sortorder ASC'; 295 $results = $DB->get_recordset_sql($sql, $params); 296 $instances = array(); 297 foreach ($results as $result) { 298 $comp = new competency(0, $result); 299 $instances[$comp->get('id')] = $comp; 300 } 301 $results->close(); 302 303 return $instances; 304 } 305 306 /** 307 * Get a single competency from the course (only if it is really in the course). 308 * 309 * @param int $courseid The course id 310 * @param int $competencyid The competency id 311 * @return competency 312 */ 313 public static function get_competency($courseid, $competencyid) { 314 global $DB; 315 316 $sql = 'SELECT comp.* 317 FROM {' . competency::TABLE . '} comp 318 JOIN {' . self::TABLE . '} crscomp 319 ON crscomp.competencyid = comp.id 320 WHERE crscomp.courseid = ? AND crscomp.competencyid = ?'; 321 $params = array($courseid, $competencyid); 322 323 $result = $DB->get_record_sql($sql, $params); 324 if (!$result) { 325 throw new coding_exception('The competency does not belong to this course: ' . $competencyid . ', ' . $courseid); 326 } 327 328 return new competency(0, $result); 329 } 330 331 /** 332 * Hook to execute after delete. 333 * 334 * @param bool $result Whether or not the delete was successful. 335 * @return void 336 */ 337 protected function after_delete($result) { 338 global $DB; 339 if (!$result) { 340 return; 341 } 342 343 $table = '{' . self::TABLE . '}'; 344 $sql = "UPDATE $table SET sortorder = sortorder -1 WHERE courseid = ? AND sortorder > ?"; 345 $DB->execute($sql, array($this->get('courseid'), $this->get('sortorder'))); 346 } 347 348 /** 349 * Get the specified course_competency in this course. 350 * 351 * @param int $courseid The course id 352 * @param int $competencyid The competency id 353 * @return course_competency 354 */ 355 public static function get_course_competency($courseid, $competencyid) { 356 global $DB; 357 358 $sql = 'SELECT crscomp.* 359 FROM {' . self::TABLE . '} crscomp 360 WHERE crscomp.courseid = ? AND crscomp.competencyid = ?'; 361 $params = array($courseid, $competencyid); 362 363 $result = $DB->get_record_sql($sql, $params); 364 if (!$result) { 365 throw new coding_exception('The competency does not belong to this course: ' . $competencyid . ', ' . $courseid); 366 } 367 368 return new course_competency(0, $result); 369 } 370 371 /** 372 * List the course_competencies in this course. 373 * 374 * @param int $courseid The course id 375 * @return course_competency[] 376 */ 377 public static function list_course_competencies($courseid) { 378 global $DB; 379 380 $sql = 'SELECT coursecomp.* 381 FROM {' . self::TABLE . '} coursecomp 382 JOIN {' . competency::TABLE . '} comp 383 ON coursecomp.competencyid = comp.id 384 WHERE coursecomp.courseid = ?'; 385 $params = array($courseid); 386 387 $sql .= ' ORDER BY coursecomp.sortorder ASC'; 388 $results = $DB->get_recordset_sql($sql, $params); 389 $instances = array(); 390 foreach ($results as $result) { 391 array_push($instances, new course_competency(0, $result)); 392 } 393 $results->close(); 394 395 return $instances; 396 } 397 398 /** 399 * Check if course competency has records for competencies. 400 * 401 * @param array $competencyids Array of competencies ids. 402 * @return boolean Return true if one or more than a competency was found in a course. 403 */ 404 public static function has_records_for_competencies($competencyids) { 405 global $DB; 406 list($insql, $params) = $DB->get_in_or_equal($competencyids, SQL_PARAMS_NAMED); 407 return self::record_exists_select("competencyid $insql", $params); 408 } 409 410 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body