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 user_competency persistence.
19
 *
20
 * @package    core_competency
21
 * @copyright  2015 Serge Gauthier
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 context_course;
29
use context_user;
30
use comment;
31
use lang_string;
32
 
33
/**
34
 * Class for loading/storing user_competency from the DB.
35
 *
36
 * @copyright  2015 Serge Gauthier
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 */
39
class user_competency extends persistent {
40
 
41
    /** Table name for user_competency persistency */
42
    const TABLE = 'competency_usercomp';
43
 
44
    /** Idle status */
45
    const STATUS_IDLE = 0;
46
 
47
    /** Waiting for review status */
48
    const STATUS_WAITING_FOR_REVIEW = 1;
49
 
50
    /** In review status */
51
    const STATUS_IN_REVIEW = 2;
52
 
53
    /**
54
     * Return the definition of the properties of this model.
55
     *
56
     * @return array
57
     */
58
    protected static function define_properties() {
59
        return array(
60
            'userid' => array(
61
                'type' => PARAM_INT,
62
            ),
63
            'competencyid' => array(
64
                'type' => PARAM_INT,
65
            ),
66
            'status' => array(
67
                'choices' => array(
68
                    self::STATUS_IDLE,
69
                    self::STATUS_WAITING_FOR_REVIEW,
70
                    self::STATUS_IN_REVIEW,
71
                ),
72
                'type' => PARAM_INT,
73
                'default' => self::STATUS_IDLE,
74
            ),
75
            'reviewerid' => array(
76
                'type' => PARAM_INT,
77
                'default' => null,
78
                'null' => NULL_ALLOWED,
79
            ),
80
            'proficiency' => array(
81
                'type' => PARAM_BOOL,
82
                'default' => null,
83
                'null' => NULL_ALLOWED,
84
            ),
85
            'grade' => array(
86
                'type' => PARAM_INT,
87
                'default' => null,
88
                'null' => NULL_ALLOWED,
89
            ),
90
        );
91
    }
92
 
93
    /**
94
     * Whether the current user can comment on this user competency.
95
     *
96
     * @return bool
97
     */
98
    public function can_comment() {
99
        return static::can_comment_user($this->get('userid'));
100
    }
101
 
102
    /**
103
     * Whether the current user can read this user competency.
104
     *
105
     * @return bool
106
     */
107
    public function can_read() {
108
        return static::can_read_user($this->get('userid'));
109
    }
110
 
111
    /**
112
     * Whether the current user can read comments on this user competency.
113
     *
114
     * @return bool
115
     */
116
    public function can_read_comments() {
117
        return static::can_read_comments_user($this->get('userid'));
118
    }
119
 
120
    /**
121
     * Can the current user send the user competency for review?
122
     *
123
     * @return bool
124
     */
125
    public function can_request_review() {
126
        return static::can_request_review_user($this->get('userid'));
127
    }
128
 
129
    /**
130
     * Can the current user review the user competency?
131
     *
132
     * @return bool
133
     */
134
    public function can_review() {
135
        return static::can_review_user($this->get('userid'));
136
    }
137
 
138
    /**
139
     * Human readable status name.
140
     *
141
     * @param int $status The status code.
142
     * @return lang_string
143
     */
144
    public static function get_status_name($status) {
145
 
146
        switch ($status) {
147
            case self::STATUS_IDLE:
148
                $strname = 'idle';
149
                break;
150
            case self::STATUS_WAITING_FOR_REVIEW:
151
                $strname = 'waitingforreview';
152
                break;
153
            case self::STATUS_IN_REVIEW:
154
                $strname = 'inreview';
155
                break;
156
            default:
157
                throw new \moodle_exception('errorusercomptencystatus', 'core_competency', '', $status);
158
                break;
159
        }
160
 
161
        return new lang_string('usercompetencystatus_' . $strname, 'core_competency');
162
    }
163
 
164
    /**
165
     * Get list of competency status.
166
     *
167
     * @return array
168
     */
169
    public static function get_status_list() {
170
 
171
        static $list = null;
172
 
173
        if ($list === null) {
174
            $list = array(
175
                self::STATUS_IDLE => self::get_status_name(self::STATUS_IDLE),
176
                self::STATUS_WAITING_FOR_REVIEW => self::get_status_name(self::STATUS_WAITING_FOR_REVIEW),
177
                self::STATUS_IN_REVIEW => self::get_status_name(self::STATUS_IN_REVIEW));
178
        }
179
 
180
        return $list;
181
    }
182
 
183
    /**
184
     * Get the comment object.
185
     *
186
     * @return comment
187
     */
188
    public function get_comment_object() {
189
        global $CFG;
190
        require_once($CFG->dirroot . '/comment/lib.php');
191
 
192
        if (!$this->get('id')) {
193
            throw new coding_exception('The user competency record must exist.');
194
        }
195
 
196
        $comment = new comment((object) array(
197
            'context' => $this->get_context(),
198
            'component' => 'competency',    // This cannot be named 'core_competency'.
199
            'itemid' => $this->get('id'),
200
            'area' => 'user_competency',
201
            'showcount' => true,
202
        ));
203
        $comment->set_fullwidth(true);
204
        return $comment;
205
    }
206
 
207
    /**
208
     * Return the competency Object.
209
     *
210
     * @return competency Competency Object
211
     */
212
    public function get_competency() {
213
        return new competency($this->get('competencyid'));
214
    }
215
 
216
    /**
217
     * Get the context.
218
     *
219
     * @return \context The context.
220
     */
221
    public function get_context() {
222
        return context_user::instance($this->get('userid'));
223
    }
224
 
225
    /**
226
     * Find the plans for the user and this competency.
227
     *
228
     * Note that this:
229
     * - does not perform any capability check.
230
     * - may return completed plans.
231
     * - may return an empty array.
232
     *
233
     * @return plans[]
234
     */
235
    public function get_plans() {
236
        return plan::get_by_user_and_competency($this->get('userid'), $this->get('competencyid'));
237
    }
238
 
239
    /**
240
     * Validate the user ID.
241
     *
242
     * @param int $value The value.
243
     * @return true|lang_string
244
     */
245
    protected function validate_userid($value) {
246
        global $DB;
247
 
248
        if (!$DB->record_exists('user', array('id' => $value))) {
249
            return new lang_string('invaliduserid', 'error');
250
        }
251
 
252
        return true;
253
    }
254
 
255
    /**
256
     * Validate the competency ID.
257
     *
258
     * @param int $value The value.
259
     * @return true|lang_string
260
     */
261
    protected function validate_competencyid($value) {
262
        if (!competency::record_exists($value)) {
263
            return new lang_string('errornocompetency', 'core_competency', $value);
264
        }
265
 
266
        return true;
267
    }
268
 
269
    /**
270
     * Validate the proficiency.
271
     *
272
     * @param int $value The value.
273
     * @return true|lang_string
274
     */
275
    protected function validate_proficiency($value) {
276
        $grade = $this->get('grade');
277
 
278
        if ($grade !== null && $value === null) {
279
            // We must set a proficiency when we set a grade.
280
            return new lang_string('invaliddata', 'error');
281
 
282
        } else if ($grade === null && $value !== null) {
283
            // We must not set a proficiency when we don't set a grade.
284
            return new lang_string('invaliddata', 'error');
285
        }
286
 
287
        return true;
288
    }
289
 
290
    /**
291
     * Validate the reviewer ID.
292
     *
293
     * @param int $value The value.
294
     * @return true|lang_string
295
     */
296
    protected function validate_reviewerid($value) {
297
        global $DB;
298
 
299
        if ($value !== null && !$DB->record_exists('user', array('id' => $value))) {
300
            return new lang_string('invaliduserid', 'error');
301
        }
302
 
303
        return true;
304
    }
305
 
306
    /**
307
     * Validate the grade.
308
     *
309
     * @param int $value The value.
310
     * @return true|lang_string
311
     */
312
    protected function validate_grade($value) {
313
        if ($value !== null) {
314
            if ($value <= 0) {
315
                return new lang_string('invalidgrade', 'core_competency');
316
            }
317
 
318
            // TODO MDL-52243 Use a core method to validate the grade_scale item.
319
            // Check if grade exist in the scale item values.
320
            $competency = $this->get_competency();
321
            if (!array_key_exists($value - 1 , $competency->get_scale()->scale_items)) {
322
                return new lang_string('invalidgrade', 'core_competency');
323
            }
324
        }
325
 
326
        return true;
327
    }
328
 
329
    /**
330
     * Can the current user comment on a user's competency?
331
     *
332
     * @param int $userid The user ID the competency belongs to.
333
     * @return bool
334
     */
335
    public static function can_comment_user($userid) {
336
        global $USER;
337
 
338
        $capabilities = array('moodle/competency:usercompetencycomment');
339
        if ($USER->id == $userid) {
340
            $capabilities[] = 'moodle/competency:usercompetencycommentown';
341
        }
342
 
343
        if (has_any_capability($capabilities, context_user::instance($userid))) {
344
            return true;
345
        }
346
 
347
        return false;
348
    }
349
 
350
    /**
351
     * Can the current user grade a user's user competency?
352
     *
353
     * @param int $userid The user ID the competency belongs to.
354
     * @return bool
355
     */
356
    public static function can_grade_user($userid) {
357
        $ratecap = 'moodle/competency:competencygrade';
358
        return has_capability($ratecap, context_user::instance($userid));
359
    }
360
 
361
    /**
362
     * Can the current user grade a user's user competency in a course?
363
     *
364
     * @param int $userid The user ID the competency belongs to.
365
     * @param int $courseid The course ID.
366
     * @return bool
367
     */
368
    public static function can_grade_user_in_course($userid, $courseid) {
369
        $ratecap = 'moodle/competency:competencygrade';
370
        return has_capability($ratecap, context_course::instance($courseid))
371
            || static::can_grade_user($userid);
372
    }
373
 
374
    /**
375
     * Can the current user read the comments on a user's competency?
376
     *
377
     * @param int $userid The user ID the competency belongs to.
378
     * @return bool
379
     */
380
    public static function can_read_comments_user($userid) {
381
        // Everyone who can read the user competency can read the comments.
382
        return static::can_read_user($userid);
383
    }
384
 
385
    /**
386
     * Can the current user read the user competencies of a user in a course?
387
     *
388
     * @param int $userid The user ID the competency belongs to.
389
     * @param int $courseid The course ID.
390
     * @return bool
391
     */
392
    public static function can_read_user_in_course($userid, $courseid) {
393
        $capability = 'moodle/competency:usercompetencyview';
394
        return has_capability($capability, context_course::instance($courseid))
395
            || static::can_read_user($userid);
396
    }
397
 
398
    /**
399
     * Can the current user read a user's competency?
400
     *
401
     * @param int $userid The user ID the competency belongs to.
402
     * @return bool
403
     */
404
    public static function can_read_user($userid) {
405
        $capability = 'moodle/competency:usercompetencyview';
406
        return has_capability($capability, context_user::instance($userid))
407
            || plan::can_read_user($userid);
408
    }
409
 
410
    /**
411
     * Can the current user send a user's competency for review?
412
     *
413
     * Note that the status 'review' is not meant to be used for student to self-assess
414
     * themselves, then to ask the teacher to review their assessment. It is more intended
415
     * for a student to provide evidence of prior learning and request their review.
416
     *
417
     * @param int $userid The user ID the competency belongs to.
418
     * @return bool
419
     */
420
    public static function can_request_review_user($userid) {
421
        global $USER;
422
 
423
        $capabilities = array('moodle/competency:usercompetencyrequestreview');
424
        if ($USER->id == $userid) {
425
            $capabilities[] = 'moodle/competency:usercompetencyrequestreviewown';
426
        }
427
 
428
        if (has_any_capability($capabilities, context_user::instance($userid))) {
429
            return true;
430
        }
431
 
432
        return false;
433
    }
434
 
435
    /**
436
     * Can the current user review the user competency?
437
     *
438
     * @param int $userid The user ID the competency belongs to.
439
     * @return bool
440
     */
441
    public static function can_review_user($userid) {
442
        $capability = 'moodle/competency:usercompetencyreview';
443
        return has_capability($capability, context_user::instance($userid));
444
    }
445
 
446
    /**
447
     * Create a new user_competency object.
448
     *
449
     * Note, this is intended to be used to create a blank relation, for instance when
450
     * the record was not found in the database. This does not save the model.
451
     *
452
     * @param  int $userid The user ID.
453
     * @param  int $competencyid The competency ID.
454
     * @return \core_competency\user_competency
455
     */
456
    public static function create_relation($userid, $competencyid) {
457
        $relation = new user_competency(0, (object) array('userid' => $userid, 'competencyid' => $competencyid));
458
        return $relation;
459
    }
460
 
461
    /**
462
     * Fetch a competency by user competency ID.
463
     *
464
     * This is a convenience method to attempt to efficiently fetch a competency when
465
     * the only information we have is the user_competency ID, in evidence for instance.
466
     *
467
     * @param  int $id The user competency ID.
468
     * @return competency
469
     */
470
    public static function get_competency_by_usercompetencyid($id) {
471
        global $DB;
472
        $sql = "SELECT c.*
473
                  FROM {" . self::TABLE . "} uc
474
                  JOIN {" . competency::TABLE . "} c
475
                    ON c.id = uc.competencyid
476
                 WHERE uc.id = ?";
477
        $record = $DB->get_record_sql($sql, array($id), MUST_EXIST);
478
        return new competency(0, $record);
479
    }
480
 
481
    /**
482
     * Get multiple user_competency for a user.
483
     *
484
     * @param  int $userid
485
     * @param  array  $competenciesorids Limit search to those competencies, or competency IDs.
486
     * @return \core_competency\user_competency[]
487
     */
488
    public static function get_multiple($userid, array $competenciesorids = null) {
489
        global $DB;
490
 
491
        $params = array();
492
        $params['userid'] = $userid;
493
        $sql = '1 = 1';
494
 
495
        if (!empty($competenciesorids)) {
496
            $test = reset($competenciesorids);
497
            if (is_number($test)) {
498
                $ids = $competenciesorids;
499
            } else {
500
                $ids = array();
501
                foreach ($competenciesorids as $comp) {
502
                    $ids[] = $comp->get('id');
503
                }
504
            }
505
 
506
            list($insql, $inparams) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED);
507
            $params += $inparams;
508
            $sql = "competencyid $insql";
509
        }
510
 
511
        // Order by ID to prevent random ordering.
512
        return self::get_records_select("userid = :userid AND $sql", $params, 'id ASC');
513
    }
514
 
515
    /**
516
     * Checks if a competency has user competency records.
517
     *
518
     * @param  int $competencyid The competency ID
519
     * @return boolean
520
     */
521
    public static function has_records_for_competency($competencyid) {
522
        return self::record_exists_select('competencyid = ?', array($competencyid));
523
    }
524
 
525
    /**
526
     * Checks if any of the competencies of a framework has a user competency record.
527
     *
528
     * @param  int $frameworkid The competency framework ID.
529
     * @return boolean
530
     */
531
    public static function has_records_for_framework($frameworkid) {
532
        global $DB;
533
 
534
        $sql = "SELECT 'x'
535
                  FROM {" . self::TABLE . "} uc
536
                  JOIN {" . competency::TABLE . "} c
537
                    ON uc.competencyid = c.id
538
                 WHERE c.competencyframeworkid = ?";
539
        $params = array($frameworkid);
540
 
541
        return $DB->record_exists_sql($sql, $params);
542
    }
543
 
544
    /**
545
     * Check if user competency has records for competencies.
546
     *
547
     * @param array $competencyids The competencies ids.
548
     * @return boolean Return true if the delete was successfull.
549
     */
550
    public static function has_records_for_competencies($competencyids) {
551
        global $DB;
552
        list($insql, $params) = $DB->get_in_or_equal($competencyids, SQL_PARAMS_NAMED);
553
        return self::record_exists_select("competencyid $insql", $params);
554
    }
555
 
556
}