2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * Evidence persistent file.
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
25 namespace core_competency
;
26 defined('MOODLE_INTERNAL') ||
die();
36 * Evidence persistent class.
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
42 class evidence
extends persistent
{
44 const TABLE
= 'competency_evidence';
46 /** Action logging. */
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;
54 * Return the definition of the properties of this model.
58 protected static function define_properties() {
60 'usercompetencyid' => array(
68 'choices' => array(self
::ACTION_LOG
, self
::ACTION_COMPLETE
, self
::ACTION_OVERRIDE
)
70 'actionuserid' => array(
73 'null' => NULL_ALLOWED
75 'descidentifier' => array(
76 'type' => PARAM_STRINGID
78 'desccomponent' => array(
79 'type' => PARAM_COMPONENT
84 'null' => NULL_ALLOWED
89 'null' => NULL_ALLOWED
94 'null' => NULL_ALLOWED
97 'type' => PARAM_NOTAGS
,
99 'null' => NULL_ALLOWED
105 * Return the competency linked to this.
109 public function get_competency() {
110 return user_competency
::get_competency_by_usercompetencyid($this->get('usercompetencyid'));
114 * Return the evidence's context.
118 public function get_context() {
119 return context
::instance_by_id($this->get('contextid'));
123 * Convenience method to get the description $a.
127 protected function get_desca() {
128 $value = $this->raw_get('desca');
129 if ($value !== null) {
130 $value = json_decode($value);
136 * Convenience method to get the description.
138 * @return lang_string
140 public function get_description() {
141 return new lang_string($this->get('descidentifier'), $this->get('desccomponent'), $this->get_desca());
145 * Convenience method to set the description $a.
147 * @param mixed $value
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.');
155 $value = json_encode($value);
157 $this->raw_set('desca', $value);
161 * Convenience method handling moodle_urls.
163 * @param null|string|moodle_url $url The URL.
165 protected function set_url($url) {
166 if ($url instanceof \moodle_url
) {
167 $url = $url->out(false);
169 $this->raw_set('url', $url);
173 * Validate the action user ID.
175 * @param int $value A user ID.
176 * @return true|lang_string
178 protected function validate_actionuserid($value) {
179 if ($value !== null && !\core_user
::is_real_user($value)) {
180 return new lang_string('invaliddata', 'error');
186 * Validate the context ID.
189 * @return true|lang_string
191 protected function validate_contextid($value) {
193 context
::instance_by_id($value);
194 } catch (moodle_exception
$e) {
195 // That does not look good...
196 return new lang_string('invaliddata', 'error');
202 * Validate the description $a.
204 * @param string $value
205 * @return true|lang_string
207 protected function validate_desca($value) {
208 if ($value === null) {
212 $desc = json_decode($value);
213 if ($desc === null && json_last_error() !== JSON_ERROR_NONE
) {
214 return new lang_string('invaliddata', 'error');
221 * Validate the description identifier.
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.
228 * @param string $value
229 * @return true|lang_string
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');
240 * Validate the grade.
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.
245 * @param int $value The value.
246 * @return true|lang_string
248 protected function validate_grade($value) {
249 if ($value !== null && $value <= 0) {
250 return new lang_string('invalidgrade', 'core_competency');
253 $action = $this->get('action');
254 if ($value === null && $action == self
::ACTION_COMPLETE
) {
255 return new lang_string('invalidgrade', 'core_competency');
257 } else if ($value !== null && $action == self
::ACTION_LOG
) {
258 return new lang_string('invalidgrade', 'core_competency');
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');
274 * Validate the user competency.
277 * @return true|lang_string
279 protected function validate_usercompetencyid($value) {
280 if (!user_competency
::record_exists($value)) {
281 return new lang_string('invaliddata', 'error');
287 * Whether the current user can delete an evidence in the context of a user.
289 * @param int $userid The user ID the evidence belongs to.
292 public static function can_delete_user($userid) {
293 return has_capability('moodle/competency:evidencedelete', context_user
::instance($userid));
297 * Load a list of records in a context for a user competency.
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.
306 * @return \core_competency\persistent[]
308 public static function get_records_for_usercompetency($usercompetencyid,
317 'usercompid' => $usercompetencyid,
318 'path' => $context->path
. '/%',
319 'contextid' => $context->id
323 $sort = ' ORDER BY e.' . $sort . ' ' . $order . ', e.id ASC';
325 $sort = ' ORDER BY e.id ASC';
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
334 $records = $DB->get_records_sql($sql, $params, $skip, $limit);
335 $instances = array();
337 foreach ($records as $record) {
338 $newrecord = new static(0, $record);
339 array_push($instances, $newrecord);