Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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