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
 * Evidence persistent file.
19
 *
20
 * @package    core_competency
21
 * @copyright  2015 Frédéric Massart - FMCorz.net
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_competency;
26
defined('MOODLE_INTERNAL') || die();
27
 
28
use coding_exception;
29
use context;
30
use context_user;
31
use lang_string;
32
use moodle_exception;
33
use stdClass;
34
 
35
/**
36
 * Evidence persistent class.
37
 *
38
 * @package    core_competency
39
 * @copyright  2015 Frédéric Massart - FMCorz.net
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class evidence extends persistent {
43
 
44
    const TABLE = 'competency_evidence';
45
 
46
    /** Action logging. */
47
    const ACTION_LOG = 0;
48
    /** Action rating a competency when no rating is set. */
49
    const ACTION_COMPLETE = 2;
50
    /** Action rating a competency. */
51
    const ACTION_OVERRIDE = 3;
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
            'usercompetencyid' => array(
61
                'type' => PARAM_INT
62
            ),
63
            'contextid' => array(
64
                'type' => PARAM_INT
65
            ),
66
            'action' => array(
67
                'type' => PARAM_INT,
68
                'choices' => array(self::ACTION_LOG, self::ACTION_COMPLETE, self::ACTION_OVERRIDE)
69
            ),
70
            'actionuserid' => array(
71
                'type' => PARAM_INT,
72
                'default' => null,
73
                'null' => NULL_ALLOWED
74
            ),
75
            'descidentifier' => array(
76
                'type' => PARAM_STRINGID
77
            ),
78
            'desccomponent' => array(
79
                'type' => PARAM_COMPONENT
80
            ),
81
            'desca' => array(
82
                'type' => PARAM_RAW,
83
                'default' => null,
84
                'null' => NULL_ALLOWED
85
            ),
86
            'url' => array(
87
                'type' => PARAM_URL,
88
                'default' => null,
89
                'null' => NULL_ALLOWED
90
            ),
91
            'grade' => array(
92
                'type' => PARAM_INT,
93
                'default' => null,
94
                'null' => NULL_ALLOWED
95
            ),
96
            'note' => array(
97
                'type' => PARAM_NOTAGS,
98
                'default' => null,
99
                'null' => NULL_ALLOWED
100
            )
101
        );
102
    }
103
 
104
    /**
105
     * Return the competency linked to this.
106
     *
107
     * @return competency
108
     */
109
    public function get_competency() {
110
        return user_competency::get_competency_by_usercompetencyid($this->get('usercompetencyid'));
111
    }
112
 
113
    /**
114
     * Return the evidence's context.
115
     *
116
     * @return context
117
     */
118
    public function get_context() {
119
        return context::instance_by_id($this->get('contextid'));
120
    }
121
 
122
    /**
123
     * Convenience method to get the description $a.
124
     *
125
     * @return mixed
126
     */
127
    protected function get_desca() {
128
        $value = $this->raw_get('desca');
129
        if ($value !== null) {
130
            $value = json_decode($value);
131
        }
132
        return $value;
133
    }
134
 
135
    /**
136
     * Convenience method to get the description.
137
     *
138
     * @return lang_string
139
     */
140
    public function get_description() {
141
        return new lang_string($this->get('descidentifier'), $this->get('desccomponent'), $this->get_desca());
142
    }
143
 
144
    /**
145
     * Convenience method to set the description $a.
146
     *
147
     * @param mixed $value
148
     * @return mixed
149
     */
150
    protected function set_desca($value) {
151
        if ($value !== null) {
152
            if (!is_scalar($value) && !is_array($value) && !($value instanceof stdClass)) {
153
                throw new coding_exception('$a format not supported.');
154
            }
155
            $value = json_encode($value);
156
        }
157
        $this->raw_set('desca', $value);
158
    }
159
 
160
    /**
161
     * Convenience method handling moodle_urls.
162
     *
163
     * @param null|string|moodle_url $url The URL.
164
     */
165
    protected function set_url($url) {
166
        if ($url instanceof \moodle_url) {
167
            $url = $url->out(false);
168
        }
169
        $this->raw_set('url', $url);
170
    }
171
 
172
    /**
173
     * Validate the action user ID.
174
     *
175
     * @param  int $value A user ID.
176
     * @return true|lang_string
177
     */
178
    protected function validate_actionuserid($value) {
179
        if ($value !== null && !\core_user::is_real_user($value)) {
180
            return new lang_string('invaliddata', 'error');
181
        }
182
        return true;
183
    }
184
 
185
    /**
186
     * Validate the context ID.
187
     *
188
     * @param  int $value
189
     * @return true|lang_string
190
     */
191
    protected function validate_contextid($value) {
192
        try {
193
            context::instance_by_id($value);
194
        } catch (moodle_exception $e) {
195
            // That does not look good...
196
            return new lang_string('invaliddata', 'error');
197
        }
198
        return true;
199
    }
200
 
201
    /**
202
     * Validate the description $a.
203
     *
204
     * @param string $value
205
     * @return true|lang_string
206
     */
207
    protected function validate_desca($value) {
208
        if ($value === null) {
209
            return true;
210
        }
211
 
212
        $desc = json_decode($value);
213
        if ($desc === null && json_last_error() !== JSON_ERROR_NONE) {
214
            return new lang_string('invaliddata', 'error');
215
        }
216
 
217
        return true;
218
    }
219
 
220
    /**
221
     * Validate the description identifier.
222
     *
223
     * Only validate string existence during create. If the string is removed later on we should
224
     * not prevent this model from being updated. Alternatively we could check if the string has
225
     * changed before performing the check but this overhead is not required for now.
226
     * An evidence should usually never be updated anyway.
227
     *
228
     * @param  string $value
229
     * @return true|lang_string
230
     */
231
    protected function validate_descidentifier($value) {
232
        if (!$this->get('id') && !get_string_manager()->string_exists($value, $this->get('desccomponent'))) {
233
            return new lang_string('invalidevidencedesc', 'core_competency');
234
        }
235
 
236
        return true;
237
    }
238
 
239
    /**
240
     * Validate the grade.
241
     *
242
     * For performance reason we do not validate that the grade is a valid item of the
243
     * scale associated with the competency or framework.
244
     *
245
     * @param int $value The value.
246
     * @return true|lang_string
247
     */
248
    protected function validate_grade($value) {
249
        if ($value !== null && $value <= 0) {
250
            return new lang_string('invalidgrade', 'core_competency');
251
        }
252
 
253
        $action = $this->get('action');
254
        if ($value === null && $action == self::ACTION_COMPLETE) {
255
            return new lang_string('invalidgrade', 'core_competency');
256
 
257
        } else if ($value !== null && $action == self::ACTION_LOG) {
258
            return new lang_string('invalidgrade', 'core_competency');
259
        }
260
 
261
        if ($value !== null) {
262
            // TODO MDL-52243 Use a core method to validate the grade_scale item.
263
            // Check if grade exist in the scale item values.
264
            $competency = $this->get_competency();
265
            if (!array_key_exists($value - 1, $competency->get_scale()->scale_items)) {
266
                return new lang_string('invalidgrade', 'core_competency');
267
            }
268
        }
269
 
270
        return true;
271
    }
272
 
273
    /**
274
     * Validate the user competency.
275
     *
276
     * @param  int $value
277
     * @return true|lang_string
278
     */
279
    protected function validate_usercompetencyid($value) {
280
        if (!user_competency::record_exists($value)) {
281
            return new lang_string('invaliddata', 'error');
282
        }
283
        return true;
284
    }
285
 
286
    /**
287
     * Whether the current user can delete an evidence in the context of a user.
288
     *
289
     * @param int $userid The user ID the evidence belongs to.
290
     * @return bool
291
     */
292
    public static function can_delete_user($userid) {
293
        return has_capability('moodle/competency:evidencedelete', context_user::instance($userid));
294
    }
295
 
296
    /**
297
     * Load a list of records in a context for a user competency.
298
     *
299
     * @param int $usercompetencyid The id of the user competency.
300
     * @param context $context Context to filter the evidence list.
301
     * @param string $sort The field from the evidence table to sort on.
302
     * @param string $order The sort direction
303
     * @param int $skip Limitstart.
304
     * @param int $limit Number of rows to return.
305
     *
306
     * @return \core_competency\persistent[]
307
     */
308
    public static function get_records_for_usercompetency($usercompetencyid,
309
                                                          \context $context,
310
                                                          $sort = '',
311
                                                          $order = 'ASC',
312
                                                          $skip = 0,
313
                                                          $limit = 0) {
314
        global $DB;
315
 
316
        $params = array(
317
            'usercompid' => $usercompetencyid,
318
            'path' => $context->path . '/%',
319
            'contextid' => $context->id
320
        );
321
 
322
        if (!empty($sort)) {
323
            $sort = ' ORDER BY e.' . $sort . ' ' . $order . ', e.id ASC';
324
        } else {
325
            $sort = ' ORDER BY e.id ASC';
326
        }
327
 
328
        $sql = 'SELECT e.*
329
                  FROM {' . static::TABLE . '} e
330
                  JOIN {context} c ON c.id = e.contextid
331
                 WHERE (c.path LIKE :path OR c.id = :contextid)
332
                   AND e.usercompetencyid = :usercompid
333
                 ' . $sort;
334
        $records = $DB->get_records_sql($sql, $params, $skip, $limit);
335
        $instances = array();
336
 
337
        foreach ($records as $record) {
338
            $newrecord = new static(0, $record);
339
            array_push($instances, $newrecord);
340
        }
341
        return $instances;
342
    }
343
 
344
}