MDL-45170 files: check other draftfile areas when processing
[moodle.git] / competency / classes / course_competency.php
blob3033d0d5751cc875ff128b3423aef3e3b29970dd
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 * Class for loading/storing competencies from the DB.
20 * @package core_competency
21 * @copyright 2015 Damyon Wiese
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 namespace core_competency;
25 defined('MOODLE_INTERNAL') || die();
27 use coding_exception;
28 use stdClass;
29 use lang_string;
31 /**
32 * Class for loading/storing course_competencies from the DB.
34 * @copyright 2015 Damyon Wiese
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 class course_competency extends persistent {
39 const TABLE = 'competency_coursecomp';
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;
50 /**
51 * Return the definition of the properties of this model.
53 * @return array
55 protected static function define_properties() {
56 return array(
57 'courseid' => array(
58 'type' => PARAM_INT
60 'competencyid' => array(
61 'type' => PARAM_INT
63 'sortorder' => array(
64 'type' => PARAM_INT
66 'ruleoutcome' => array(
67 'choices' => array(self::OUTCOME_NONE,
68 self::OUTCOME_EVIDENCE,
69 self::OUTCOME_RECOMMEND,
70 self::OUTCOME_COMPLETE
72 'default' => self::OUTCOME_EVIDENCE,
73 'type' => PARAM_INT,
78 /**
79 * Hook to execute before validate.
81 * @return void
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'))));
89 /**
90 * Return the courses where both competency and user are.
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..
95 * @param int $competencyid The competency ID.
96 * @param int $userid The user ID.
97 * @return array Indexed by course ID.
99 public static function get_courses_with_competency_and_user($competencyid, $userid) {
100 global $CFG, $DB;
102 if (!$plugins = explode(',', $CFG->enrol_plugins_enabled)) {
103 return array();
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;
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";
137 $courses = $DB->get_records_sql($sql, $params);
138 array_map('context_helper::preload_from_record', $courses);
139 return $courses;
143 * Return a list of rules.
145 * @return array Indexed by outcome value.
147 public static function get_ruleoutcome_list() {
148 static $list = null;
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));
158 return $list;
162 * Human readable rule name.
164 * @param int $ruleoutcome The value of ruleoutcome.
165 * @return lang_string
167 public static function get_ruleoutcome_name($ruleoutcome) {
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;
187 return new lang_string('coursecompetencyoutcome_' . $strname, 'core_competency');
191 * Validate course ID.
193 * @param int $data The course ID.
194 * @return true|lang_string
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');
201 return true;
205 * Validate competency ID.
207 * @param int $data The competency ID.
208 * @return true|lang_string
210 protected function validate_competencyid($data) {
211 if (!competency::record_exists($data)) {
212 return new lang_string('invaliddata', 'error');
214 return true;
218 * Return the course IDs and visible flags that include this competency.
220 * Only the ids and visible flag are returned, for the full records use list_courses.
222 * @param int $competencyid The competency id
223 * @return array containing courseid and visible.
225 public static function list_courses_min($competencyid) {
226 global $DB;
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));
234 return $results;
238 * Return partial course records foreach course that contains this competency.
240 * @param int $competencyid The competency id
241 * @return array[stdClass] Array of course records containg id, visible, shortname, idnumber, fullname
243 public static function list_courses($competencyid) {
244 global $DB;
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
249 FROM {course} course
250 JOIN {' . self::TABLE . '} coursecomp
251 ON coursecomp.courseid = course.id
252 WHERE coursecomp.competencyid = ? ', array($competencyid));
254 return $results;
258 * Count the competencies in this course.
260 * @param int $courseid The course id
261 * @return int
263 public static function count_competencies($courseid) {
264 global $DB;
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);
273 $results = $DB->count_records_sql($sql, $params);
275 return $results;
279 * List the competencies in this course.
281 * @param int $courseid The course id
282 * @return competency[] Indexed by competency ID.
284 public static function list_competencies($courseid) {
285 global $DB;
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);
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;
301 $results->close();
303 return $instances;
307 * Get a single competency from the course (only if it is really in the course).
309 * @param int $courseid The course id
310 * @param int $competencyid The competency id
311 * @return competency
313 public static function get_competency($courseid, $competencyid) {
314 global $DB;
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);
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);
328 return new competency(0, $result);
332 * Hook to execute after delete.
334 * @param bool $result Whether or not the delete was successful.
335 * @return void
337 protected function after_delete($result) {
338 global $DB;
339 if (!$result) {
340 return;
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')));
349 * Get the specified course_competency in this course.
351 * @param int $courseid The course id
352 * @param int $competencyid The competency id
353 * @return course_competency
355 public static function get_course_competency($courseid, $competencyid) {
356 global $DB;
358 $sql = 'SELECT crscomp.*
359 FROM {' . self::TABLE . '} crscomp
360 WHERE crscomp.courseid = ? AND crscomp.competencyid = ?';
361 $params = array($courseid, $competencyid);
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);
368 return new course_competency(0, $result);
372 * List the course_competencies in this course.
374 * @param int $courseid The course id
375 * @return course_competency[]
377 public static function list_course_competencies($courseid) {
378 global $DB;
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);
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));
393 $results->close();
395 return $instances;
399 * Check if course competency has records for competencies.
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.
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);