PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/competency/classes/course_competency.php

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