Commit | Line | Data |
---|---|---|
2ab34819 JL |
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 | * Database module external API | |
19 | * | |
20 | * @package mod_data | |
21 | * @category external | |
22 | * @copyright 2015 Juan Leyva <juan@moodle.com> | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | * @since Moodle 2.9 | |
25 | */ | |
26 | ||
27 | defined('MOODLE_INTERNAL') || die; | |
28 | ||
29 | require_once("$CFG->libdir/externallib.php"); | |
9fac7c86 | 30 | require_once($CFG->dirroot . "/mod/data/locallib.php"); |
2ab34819 | 31 | |
f97305b0 | 32 | use mod_data\external\database_summary_exporter; |
ef6aea9d JL |
33 | use mod_data\external\record_exporter; |
34 | use mod_data\external\content_exporter; | |
a934c896 | 35 | use mod_data\external\field_exporter; |
f97305b0 | 36 | |
2ab34819 JL |
37 | /** |
38 | * Database module external functions | |
39 | * | |
40 | * @package mod_data | |
41 | * @category external | |
42 | * @copyright 2015 Juan Leyva <juan@moodle.com> | |
43 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
44 | * @since Moodle 2.9 | |
45 | */ | |
46 | class mod_data_external extends external_api { | |
47 | ||
48 | /** | |
49 | * Describes the parameters for get_databases_by_courses. | |
50 | * | |
9db43c73 | 51 | * @return external_function_parameters |
2ab34819 JL |
52 | * @since Moodle 2.9 |
53 | */ | |
54 | public static function get_databases_by_courses_parameters() { | |
55 | return new external_function_parameters ( | |
56 | array( | |
57 | 'courseids' => new external_multiple_structure( | |
58 | new external_value(PARAM_INT, 'course id', VALUE_REQUIRED), | |
59 | 'Array of course ids', VALUE_DEFAULT, array() | |
60 | ), | |
61 | ) | |
62 | ); | |
63 | } | |
64 | ||
65 | /** | |
66 | * Returns a list of databases in a provided list of courses, | |
67 | * if no list is provided all databases that the user can view will be returned. | |
68 | * | |
69 | * @param array $courseids the course ids | |
70 | * @return array the database details | |
71 | * @since Moodle 2.9 | |
72 | */ | |
73 | public static function get_databases_by_courses($courseids = array()) { | |
f97305b0 | 74 | global $PAGE; |
2ab34819 JL |
75 | |
76 | $params = self::validate_parameters(self::get_databases_by_courses_parameters(), array('courseids' => $courseids)); | |
77 | $warnings = array(); | |
78 | ||
052da730 DP |
79 | $mycourses = array(); |
80 | if (empty($params['courseids'])) { | |
81 | $mycourses = enrol_get_my_courses(); | |
82 | $params['courseids'] = array_keys($mycourses); | |
2ab34819 JL |
83 | } |
84 | ||
85 | // Array to store the databases to return. | |
86 | $arrdatabases = array(); | |
87 | ||
88 | // Ensure there are courseids to loop through. | |
052da730 DP |
89 | if (!empty($params['courseids'])) { |
90 | ||
91 | list($dbcourses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses); | |
2ab34819 JL |
92 | |
93 | // Get the databases in this course, this function checks users visibility permissions. | |
94 | // We can avoid then additional validate_context calls. | |
95 | $databases = get_all_instances_in_courses("data", $dbcourses); | |
96 | ||
97 | foreach ($databases as $database) { | |
98 | ||
f97305b0 JL |
99 | $context = context_module::instance($database->coursemodule); |
100 | // Remove fields added by get_all_instances_in_courses. | |
101 | unset($database->coursemodule, $database->section, $database->visible, $database->groupmode, $database->groupingid); | |
2ab34819 JL |
102 | |
103 | // This information should be only available if the user can see the database entries. | |
f97305b0 JL |
104 | if (!has_capability('mod/data:viewentry', $context)) { |
105 | $fields = array('comments', 'timeavailablefrom', 'timeavailableto', 'timeviewfrom', | |
106 | 'timeviewto', 'requiredentries', 'requiredentriestoview', 'maxentries', 'rssarticles', | |
107 | 'singletemplate', 'listtemplate', 'listtemplateheader', 'listtemplatefooter', 'addtemplate', | |
108 | 'rsstemplate', 'rsstitletemplate', 'csstemplate', 'jstemplate', 'asearchtemplate', 'approval', | |
109 | 'manageapproved', 'defaultsort', 'defaultsortdir'); | |
110 | ||
111 | foreach ($fields as $field) { | |
112 | unset($database->{$field}); | |
2ab34819 JL |
113 | } |
114 | } | |
115 | ||
116 | // Check additional permissions for returning optional private settings. | |
117 | // I avoid intentionally to use can_[add|update]_moduleinfo. | |
f97305b0 JL |
118 | if (!has_capability('moodle/course:manageactivities', $context)) { |
119 | ||
120 | $fields = array('scale', 'assessed', 'assesstimestart', 'assesstimefinish', 'editany', 'notification', | |
121 | 'timemodified'); | |
122 | ||
123 | foreach ($fields as $field) { | |
124 | unset($database->{$field}); | |
2ab34819 JL |
125 | } |
126 | } | |
f97305b0 JL |
127 | $exporter = new database_summary_exporter($database, array('context' => $context)); |
128 | $arrdatabases[] = $exporter->export($PAGE->get_renderer('core')); | |
2ab34819 JL |
129 | } |
130 | } | |
131 | ||
132 | $result = array(); | |
133 | $result['databases'] = $arrdatabases; | |
134 | $result['warnings'] = $warnings; | |
135 | return $result; | |
136 | } | |
137 | ||
138 | /** | |
139 | * Describes the get_databases_by_courses return value. | |
140 | * | |
141 | * @return external_single_structure | |
142 | * @since Moodle 2.9 | |
143 | */ | |
144 | public static function get_databases_by_courses_returns() { | |
145 | ||
146 | return new external_single_structure( | |
147 | array( | |
148 | 'databases' => new external_multiple_structure( | |
f97305b0 | 149 | database_summary_exporter::get_read_structure() |
2ab34819 JL |
150 | ), |
151 | 'warnings' => new external_warnings(), | |
152 | ) | |
153 | ); | |
154 | } | |
155 | ||
cac43b9b JL |
156 | /** |
157 | * Utility function for validating a database. | |
158 | * | |
159 | * @param int $databaseid database instance id | |
160 | * @return array array containing the database object, course, context and course module objects | |
161 | * @since Moodle 3.3 | |
162 | */ | |
163 | protected static function validate_database($databaseid) { | |
164 | global $DB; | |
165 | ||
166 | // Request and permission validation. | |
167 | $database = $DB->get_record('data', array('id' => $databaseid), '*', MUST_EXIST); | |
168 | list($course, $cm) = get_course_and_cm_from_instance($database, 'data'); | |
169 | ||
170 | $context = context_module::instance($cm->id); | |
171 | self::validate_context($context); | |
172 | require_capability('mod/data:viewentry', $context); | |
173 | ||
174 | return array($database, $course, $cm, $context); | |
175 | } | |
176 | ||
9fac7c86 JL |
177 | /** |
178 | * Returns description of method parameters | |
179 | * | |
180 | * @return external_function_parameters | |
181 | * @since Moodle 3.3 | |
182 | */ | |
183 | public static function view_database_parameters() { | |
184 | return new external_function_parameters( | |
185 | array( | |
186 | 'databaseid' => new external_value(PARAM_INT, 'data instance id') | |
187 | ) | |
188 | ); | |
189 | } | |
190 | ||
191 | /** | |
192 | * Simulate the data/view.php web interface page: trigger events, completion, etc... | |
193 | * | |
194 | * @param int $databaseid the data instance id | |
195 | * @return array of warnings and status result | |
196 | * @since Moodle 3.3 | |
197 | * @throws moodle_exception | |
198 | */ | |
199 | public static function view_database($databaseid) { | |
9fac7c86 JL |
200 | |
201 | $params = self::validate_parameters(self::view_database_parameters(), array('databaseid' => $databaseid)); | |
202 | $warnings = array(); | |
203 | ||
cac43b9b | 204 | list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); |
9fac7c86 JL |
205 | |
206 | // Call the data/lib API. | |
cac43b9b | 207 | data_view($database, $course, $cm, $context); |
9fac7c86 JL |
208 | |
209 | $result = array(); | |
210 | $result['status'] = true; | |
211 | $result['warnings'] = $warnings; | |
212 | return $result; | |
213 | } | |
214 | ||
215 | /** | |
216 | * Returns description of method result value | |
217 | * | |
218 | * @return external_description | |
219 | * @since Moodle 3.3 | |
220 | */ | |
221 | public static function view_database_returns() { | |
222 | return new external_single_structure( | |
223 | array( | |
224 | 'status' => new external_value(PARAM_BOOL, 'status: true if success'), | |
225 | 'warnings' => new external_warnings() | |
226 | ) | |
227 | ); | |
228 | } | |
229 | ||
cac43b9b JL |
230 | /** |
231 | * Returns description of method parameters. | |
232 | * | |
233 | * @return external_function_parameters | |
234 | * @since Moodle 3.3 | |
235 | */ | |
236 | public static function get_data_access_information_parameters() { | |
237 | return new external_function_parameters( | |
238 | array( | |
239 | 'databaseid' => new external_value(PARAM_INT, 'Database instance id.'), | |
240 | 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group.', | |
241 | VALUE_DEFAULT, 0), | |
242 | ) | |
243 | ); | |
244 | } | |
245 | ||
246 | /** | |
247 | * Return access information for a given database. | |
248 | * | |
249 | * @param int $databaseid the database instance id | |
250 | * @param int $groupid (optional) group id, 0 means that the function will determine the user group | |
251 | * @return array of warnings and access information | |
252 | * @since Moodle 3.3 | |
253 | * @throws moodle_exception | |
254 | */ | |
255 | public static function get_data_access_information($databaseid, $groupid = 0) { | |
256 | ||
257 | $params = array('databaseid' => $databaseid, 'groupid' => $groupid); | |
258 | $params = self::validate_parameters(self::get_data_access_information_parameters(), $params); | |
259 | $warnings = array(); | |
260 | ||
261 | list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); | |
262 | ||
263 | $result = array( | |
264 | 'warnings' => $warnings | |
265 | ); | |
266 | ||
267 | $groupmode = groups_get_activity_groupmode($cm); | |
268 | if (!empty($params['groupid'])) { | |
269 | $groupid = $params['groupid']; | |
270 | // Determine is the group is visible to user. | |
271 | if (!groups_group_visible($groupid, $course, $cm)) { | |
272 | throw new moodle_exception('notingroup'); | |
273 | } | |
274 | } else { | |
275 | // Check to see if groups are being used here. | |
276 | if ($groupmode) { | |
277 | $groupid = groups_get_activity_group($cm); | |
278 | // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). | |
279 | if (!groups_group_visible($groupid, $course, $cm)) { | |
280 | throw new moodle_exception('notingroup'); | |
281 | } | |
282 | } else { | |
283 | $groupid = 0; | |
284 | } | |
285 | } | |
286 | // Group related information. | |
287 | $result['groupid'] = $groupid; | |
288 | $result['canaddentry'] = data_user_can_add_entry($database, $groupid, $groupmode, $context); | |
289 | ||
290 | // Now capabilities. | |
291 | $result['canmanageentries'] = has_capability('mod/data:manageentries', $context); | |
292 | $result['canapprove'] = has_capability('mod/data:approve', $context); | |
293 | ||
294 | // Now time access restrictions. | |
295 | list($result['timeavailable'], $warnings) = data_get_time_availability_status($database, $result['canmanageentries']); | |
296 | ||
297 | // Other information. | |
298 | $result['numentries'] = data_numentries($database); | |
299 | $result['entrieslefttoadd'] = data_get_entries_left_to_add($database, $result['numentries'], $result['canmanageentries']); | |
300 | $result['entrieslefttoview'] = data_get_entries_left_to_view($database, $result['numentries'], $result['canmanageentries']); | |
301 | $result['inreadonlyperiod'] = data_in_readonly_period($database); | |
302 | ||
303 | return $result; | |
304 | } | |
305 | ||
306 | /** | |
307 | * Returns description of method result value. | |
308 | * | |
309 | * @return external_description | |
310 | * @since Moodle 3.3 | |
311 | */ | |
312 | public static function get_data_access_information_returns() { | |
313 | return new external_single_structure( | |
314 | array( | |
315 | 'groupid' => new external_value(PARAM_INT, 'User current group id (calculated)'), | |
316 | 'canaddentry' => new external_value(PARAM_BOOL, 'Whether the user can add entries or not.'), | |
317 | 'canmanageentries' => new external_value(PARAM_BOOL, 'Whether the user can manage entries or not.'), | |
318 | 'canapprove' => new external_value(PARAM_BOOL, 'Whether the user can approve entries or not.'), | |
319 | 'timeavailable' => new external_value(PARAM_BOOL, 'Whether the database is available or not by time restrictions.'), | |
320 | 'inreadonlyperiod' => new external_value(PARAM_BOOL, 'Whether the database is in read mode only.'), | |
321 | 'numentries' => new external_value(PARAM_INT, 'The number of entries the current user added.'), | |
322 | 'entrieslefttoadd' => new external_value(PARAM_INT, 'The number of entries left to complete the activity.'), | |
323 | 'entrieslefttoview' => new external_value(PARAM_INT, 'The number of entries left to view other users entries.'), | |
324 | 'warnings' => new external_warnings() | |
325 | ) | |
326 | ); | |
327 | } | |
ef6aea9d JL |
328 | |
329 | /** | |
330 | * Returns description of method parameters | |
331 | * | |
332 | * @return external_function_parameters | |
333 | * @since Moodle 3.3 | |
334 | */ | |
335 | public static function get_entries_parameters() { | |
336 | return new external_function_parameters( | |
337 | array( | |
338 | 'databaseid' => new external_value(PARAM_INT, 'data instance id'), | |
339 | 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', | |
340 | VALUE_DEFAULT, 0), | |
341 | 'returncontents' => new external_value(PARAM_BOOL, 'Whether to return contents or not. This will return each entry | |
342 | raw contents and the complete list view (using the template).', | |
343 | VALUE_DEFAULT, false), | |
344 | 'sort' => new external_value(PARAM_INT, 'Sort the records by this field id, reserved ids are: | |
345 | 0: timeadded | |
346 | -1: firstname | |
347 | -2: lastname | |
348 | -3: approved | |
349 | -4: timemodified. | |
350 | Empty for using the default database setting.', VALUE_DEFAULT, null), | |
351 | 'order' => new external_value(PARAM_ALPHA, 'The direction of the sorting: \'ASC\' or \'DESC\'. | |
352 | Empty for using the default database setting.', VALUE_DEFAULT, null), | |
353 | 'page' => new external_value(PARAM_INT, 'The page of records to return.', VALUE_DEFAULT, 0), | |
354 | 'perpage' => new external_value(PARAM_INT, 'The number of records to return per page', VALUE_DEFAULT, 0), | |
355 | ) | |
356 | ); | |
357 | } | |
358 | ||
359 | /** | |
360 | * Return access information for a given feedback | |
361 | * | |
362 | * @param int $databaseid the data instance id | |
363 | * @param int $groupid (optional) group id, 0 means that the function will determine the user group | |
364 | * @param bool $returncontents Whether to return the entries contents or not | |
365 | * @param str $sort sort by this field | |
366 | * @param int $order the direction of the sorting | |
367 | * @param int $page page of records to return | |
368 | * @param int $perpage number of records to return per page | |
369 | * @return array of warnings and the entries | |
370 | * @since Moodle 3.3 | |
371 | * @throws moodle_exception | |
372 | */ | |
373 | public static function get_entries($databaseid, $groupid = 0, $returncontents = false, $sort = null, $order = null, | |
374 | $page = 0, $perpage = 0) { | |
375 | global $PAGE, $DB; | |
376 | ||
377 | $params = array('databaseid' => $databaseid, 'groupid' => $groupid, 'returncontents' => $returncontents , | |
378 | 'sort' => $sort, 'order' => $order, 'page' => $page, 'perpage' => $perpage); | |
379 | $params = self::validate_parameters(self::get_entries_parameters(), $params); | |
380 | $warnings = array(); | |
381 | ||
382 | if (!empty($params['order'])) { | |
383 | $params['order'] = strtoupper($params['order']); | |
384 | if ($params['order'] != 'ASC' && $params['order'] != 'DESC') { | |
385 | throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $params['order'] . ')'); | |
386 | } | |
387 | } | |
388 | ||
389 | list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); | |
390 | // Check database is open in time. | |
391 | data_require_time_available($database, null, $context); | |
392 | ||
393 | if (!empty($params['groupid'])) { | |
394 | $groupid = $params['groupid']; | |
395 | // Determine is the group is visible to user. | |
396 | if (!groups_group_visible($groupid, $course, $cm)) { | |
397 | throw new moodle_exception('notingroup'); | |
398 | } | |
399 | } else { | |
400 | // Check to see if groups are being used here. | |
401 | if ($groupmode = groups_get_activity_groupmode($cm)) { | |
402 | $groupid = groups_get_activity_group($cm); | |
403 | // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). | |
404 | if (!groups_group_visible($groupid, $course, $cm)) { | |
405 | throw new moodle_exception('notingroup'); | |
406 | } | |
407 | } else { | |
408 | $groupid = 0; | |
409 | } | |
410 | } | |
411 | ||
412 | list($records, $maxcount, $totalcount, $page, $nowperpage, $sort, $mode) = | |
413 | data_search_entries($database, $cm, $context, 'list', $groupid, '', $params['sort'], $params['order'], | |
414 | $params['page'], $params['perpage']); | |
415 | ||
416 | $entries = []; | |
417 | $contentsids = []; // Store here the content ids of the records returned. | |
418 | foreach ($records as $record) { | |
419 | $user = user_picture::unalias($record, null, 'userid'); | |
420 | $related = array('context' => $context, 'database' => $database, 'user' => $user); | |
421 | ||
422 | $contents = $DB->get_records('data_content', array('recordid' => $record->id)); | |
423 | $contentsids = array_merge($contentsids, array_keys($contents)); | |
424 | if ($params['returncontents']) { | |
425 | $related['contents'] = $contents; | |
426 | } else { | |
427 | $related['contents'] = null; | |
428 | } | |
429 | ||
430 | $exporter = new record_exporter($record, $related); | |
431 | $entries[] = $exporter->export($PAGE->get_renderer('core')); | |
432 | } | |
433 | ||
434 | // Retrieve total files size for the records retrieved. | |
435 | $totalfilesize = 0; | |
436 | $fs = get_file_storage(); | |
437 | $files = $fs->get_area_files($context->id, 'mod_data', 'content'); | |
438 | foreach ($files as $file) { | |
439 | if ($file->is_directory() || !in_array($file->get_itemid(), $contentsids)) { | |
440 | continue; | |
441 | } | |
442 | $totalfilesize += $file->get_filesize(); | |
443 | } | |
444 | ||
445 | $result = array( | |
446 | 'entries' => $entries, | |
447 | 'totalcount' => $totalcount, | |
448 | 'totalfilesize' => $totalfilesize, | |
449 | 'warnings' => $warnings | |
450 | ); | |
451 | ||
452 | // Check if we should return the list rendered. | |
453 | if ($params['returncontents']) { | |
454 | ob_start(); | |
455 | // The return parameter stops the execution after the first record. | |
456 | data_print_template('listtemplate', $records, $database, '', $page, false); | |
457 | $result['listviewcontents'] = ob_get_contents(); | |
458 | ob_end_clean(); | |
459 | } | |
460 | ||
461 | return $result; | |
462 | } | |
463 | ||
464 | /** | |
465 | * Returns description of method result value | |
466 | * | |
467 | * @return external_description | |
468 | * @since Moodle 3.3 | |
469 | */ | |
470 | public static function get_entries_returns() { | |
471 | return new external_single_structure( | |
472 | array( | |
473 | 'entries' => new external_multiple_structure( | |
474 | record_exporter::get_read_structure() | |
475 | ), | |
476 | 'totalcount' => new external_value(PARAM_INT, 'Total count of records.'), | |
477 | 'totalfilesize' => new external_value(PARAM_INT, 'Total size (bytes) of the files included in the records.'), | |
478 | 'listviewcontents' => new external_value(PARAM_RAW, 'The list view contents as is rendered in the site.', | |
479 | VALUE_OPTIONAL), | |
480 | 'warnings' => new external_warnings() | |
481 | ) | |
482 | ); | |
483 | } | |
771effef JL |
484 | |
485 | /** | |
486 | * Returns description of method parameters | |
487 | * | |
488 | * @return external_function_parameters | |
489 | * @since Moodle 3.3 | |
490 | */ | |
491 | public static function get_entry_parameters() { | |
492 | return new external_function_parameters( | |
493 | array( | |
494 | 'entryid' => new external_value(PARAM_INT, 'record entry id'), | |
495 | 'returncontents' => new external_value(PARAM_BOOL, 'Whether to return contents or not.', VALUE_DEFAULT, false), | |
496 | ) | |
497 | ); | |
498 | } | |
499 | ||
500 | /** | |
501 | * Return one entry record from the database, including contents optionally. | |
502 | * | |
503 | * @param int $entryid the record entry id id | |
504 | * @param bool $returncontents whether to return the entries contents or not | |
505 | * @return array of warnings and the entries | |
506 | * @since Moodle 3.3 | |
507 | * @throws moodle_exception | |
508 | */ | |
509 | public static function get_entry($entryid, $returncontents = false) { | |
510 | global $PAGE, $DB; | |
511 | ||
512 | $params = array('entryid' => $entryid, 'returncontents' => $returncontents); | |
513 | $params = self::validate_parameters(self::get_entry_parameters(), $params); | |
514 | $warnings = array(); | |
515 | ||
516 | $record = $DB->get_record('data_records', array('id' => $params['entryid']), '*', MUST_EXIST); | |
517 | list($database, $course, $cm, $context) = self::validate_database($record->dataid); | |
518 | ||
519 | // Check database is open in time. | |
520 | $canmanageentries = has_capability('mod/data:manageentries', $context); | |
521 | data_require_time_available($database, $canmanageentries); | |
522 | ||
523 | if ($record->groupid !== 0) { | |
524 | if (!groups_group_visible($record->groupid, $course, $cm)) { | |
525 | throw new moodle_exception('notingroup'); | |
526 | } | |
527 | } | |
528 | ||
529 | // Check correct record entry. Group check was done before. | |
530 | if (!data_can_view_record($database, $record, $record->groupid, $canmanageentries)) { | |
531 | throw new moodle_exception('notapproved', 'data'); | |
532 | } | |
533 | ||
534 | $related = array('context' => $context, 'database' => $database, 'user' => null); | |
535 | if ($params['returncontents']) { | |
536 | $related['contents'] = $DB->get_records('data_content', array('recordid' => $record->id)); | |
537 | } else { | |
538 | $related['contents'] = null; | |
539 | } | |
540 | $exporter = new record_exporter($record, $related); | |
541 | $entry = $exporter->export($PAGE->get_renderer('core')); | |
542 | ||
543 | $result = array( | |
544 | 'entry' => $entry, | |
26d8bcea | 545 | 'ratinginfo' => \core_rating\external\util::get_rating_info($database, $context, 'mod_data', 'entry', array($record)), |
771effef JL |
546 | 'warnings' => $warnings |
547 | ); | |
548 | // Check if we should return the entry rendered. | |
549 | if ($params['returncontents']) { | |
550 | $records = [$record]; | |
551 | $result['entryviewcontents'] = data_print_template('singletemplate', $records, $database, '', 0, true); | |
552 | } | |
553 | ||
554 | return $result; | |
555 | } | |
556 | ||
557 | /** | |
558 | * Returns description of method result value | |
559 | * | |
560 | * @return external_description | |
561 | * @since Moodle 3.3 | |
562 | */ | |
563 | public static function get_entry_returns() { | |
564 | return new external_single_structure( | |
565 | array( | |
566 | 'entry' => record_exporter::get_read_structure(), | |
567 | 'entryviewcontents' => new external_value(PARAM_RAW, 'The entry as is rendered in the site.', VALUE_OPTIONAL), | |
26d8bcea | 568 | 'ratinginfo' => \core_rating\external\util::external_ratings_structure(), |
771effef JL |
569 | 'warnings' => new external_warnings() |
570 | ) | |
571 | ); | |
572 | } | |
a934c896 JL |
573 | |
574 | /** | |
575 | * Returns description of method parameters | |
576 | * | |
577 | * @return external_function_parameters | |
578 | * @since Moodle 3.3 | |
579 | */ | |
580 | public static function get_fields_parameters() { | |
581 | return new external_function_parameters( | |
582 | array( | |
583 | 'databaseid' => new external_value(PARAM_INT, 'Database instance id.'), | |
584 | ) | |
585 | ); | |
586 | } | |
587 | ||
588 | /** | |
589 | * Return the list of configured fields for the given database. | |
590 | * | |
591 | * @param int $databaseid the database id | |
592 | * @return array of warnings and the fields | |
593 | * @since Moodle 3.3 | |
594 | * @throws moodle_exception | |
595 | */ | |
596 | public static function get_fields($databaseid) { | |
597 | global $PAGE; | |
598 | ||
599 | $params = array('databaseid' => $databaseid); | |
600 | $params = self::validate_parameters(self::get_fields_parameters(), $params); | |
84c2a87b | 601 | $fields = $warnings = array(); |
a934c896 JL |
602 | |
603 | list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); | |
604 | ||
605 | // Check database is open in time. | |
606 | $canmanageentries = has_capability('mod/data:manageentries', $context); | |
607 | data_require_time_available($database, $canmanageentries); | |
608 | ||
609 | $fieldinstances = data_get_field_instances($database); | |
610 | ||
611 | foreach ($fieldinstances as $fieldinstance) { | |
612 | $record = $fieldinstance->field; | |
613 | // Now get the configs the user can see with his current permissions. | |
614 | $configs = $fieldinstance->get_config_for_external(); | |
615 | foreach ($configs as $name => $value) { | |
616 | // Overwrite. | |
617 | $record->{$name} = $value; | |
618 | } | |
619 | ||
620 | $exporter = new field_exporter($record, array('context' => $context)); | |
621 | $fields[] = $exporter->export($PAGE->get_renderer('core')); | |
622 | } | |
623 | ||
624 | $result = array( | |
625 | 'fields' => $fields, | |
626 | 'warnings' => $warnings | |
627 | ); | |
628 | return $result; | |
629 | } | |
630 | ||
631 | /** | |
632 | * Returns description of method result value | |
633 | * | |
634 | * @return external_description | |
635 | * @since Moodle 3.3 | |
636 | */ | |
637 | public static function get_fields_returns() { | |
638 | return new external_single_structure( | |
639 | array( | |
640 | 'fields' => new external_multiple_structure( | |
641 | field_exporter::get_read_structure() | |
642 | ), | |
643 | 'warnings' => new external_warnings() | |
644 | ) | |
645 | ); | |
646 | } | |
56b8edcb JL |
647 | |
648 | /** | |
649 | * Returns description of method parameters | |
650 | * | |
651 | * @return external_function_parameters | |
652 | * @since Moodle 3.3 | |
653 | */ | |
654 | public static function search_entries_parameters() { | |
655 | return new external_function_parameters( | |
656 | array( | |
657 | 'databaseid' => new external_value(PARAM_INT, 'data instance id'), | |
658 | 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', | |
659 | VALUE_DEFAULT, 0), | |
660 | 'returncontents' => new external_value(PARAM_BOOL, 'Whether to return contents or not.', VALUE_DEFAULT, false), | |
661 | 'search' => new external_value(PARAM_NOTAGS, 'search string (empty when using advanced)', VALUE_DEFAULT, ''), | |
662 | 'advsearch' => new external_multiple_structure( | |
663 | new external_single_structure( | |
664 | array( | |
665 | 'name' => new external_value(PARAM_ALPHANUMEXT, 'Field key for search. | |
666 | Use fn or ln for first or last name'), | |
667 | 'value' => new external_value(PARAM_RAW, 'JSON encoded value for search'), | |
668 | ) | |
669 | ), 'Advanced search', VALUE_DEFAULT, array() | |
670 | ), | |
671 | 'sort' => new external_value(PARAM_INT, 'Sort the records by this field id, reserved ids are: | |
672 | 0: timeadded | |
673 | -1: firstname | |
674 | -2: lastname | |
675 | -3: approved | |
676 | -4: timemodified. | |
677 | Empty for using the default database setting.', VALUE_DEFAULT, null), | |
678 | 'order' => new external_value(PARAM_ALPHA, 'The direction of the sorting: \'ASC\' or \'DESC\'. | |
679 | Empty for using the default database setting.', VALUE_DEFAULT, null), | |
680 | 'page' => new external_value(PARAM_INT, 'The page of records to return.', VALUE_DEFAULT, 0), | |
681 | 'perpage' => new external_value(PARAM_INT, 'The number of records to return per page', VALUE_DEFAULT, 0), | |
682 | ) | |
683 | ); | |
684 | } | |
685 | ||
686 | /** | |
687 | * Return access information for a given feedback | |
688 | * | |
689 | * @param int $databaseid the data instance id | |
690 | * @param int $groupid (optional) group id, 0 means that the function will determine the user group | |
691 | * @param bool $returncontents whether to return contents or not | |
692 | * @param str $search search text | |
693 | * @param array $advsearch advanced search data | |
694 | * @param str $sort sort by this field | |
695 | * @param int $order the direction of the sorting | |
696 | * @param int $page page of records to return | |
697 | * @param int $perpage number of records to return per page | |
698 | * @return array of warnings and the entries | |
699 | * @since Moodle 3.3 | |
700 | * @throws moodle_exception | |
701 | */ | |
702 | public static function search_entries($databaseid, $groupid = 0, $returncontents = false, $search = '', $advsearch = [], | |
703 | $sort = null, $order = null, $page = 0, $perpage = 0) { | |
704 | global $PAGE, $DB; | |
705 | ||
706 | $params = array('databaseid' => $databaseid, 'groupid' => $groupid, 'returncontents' => $returncontents, 'search' => $search, | |
707 | 'advsearch' => $advsearch, 'sort' => $sort, 'order' => $order, 'page' => $page, 'perpage' => $perpage); | |
708 | $params = self::validate_parameters(self::search_entries_parameters(), $params); | |
709 | $warnings = array(); | |
710 | ||
711 | if (!empty($params['order'])) { | |
712 | $params['order'] = strtoupper($params['order']); | |
713 | if ($params['order'] != 'ASC' && $params['order'] != 'DESC') { | |
714 | throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $params['order'] . ')'); | |
715 | } | |
716 | } | |
717 | ||
718 | list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); | |
719 | // Check database is open in time. | |
720 | data_require_time_available($database, null, $context); | |
721 | ||
722 | if (!empty($params['groupid'])) { | |
723 | $groupid = $params['groupid']; | |
724 | // Determine is the group is visible to user. | |
725 | if (!groups_group_visible($groupid, $course, $cm)) { | |
726 | throw new moodle_exception('notingroup'); | |
727 | } | |
728 | } else { | |
729 | // Check to see if groups are being used here. | |
730 | if ($groupmode = groups_get_activity_groupmode($cm)) { | |
731 | $groupid = groups_get_activity_group($cm); | |
732 | // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). | |
733 | if (!groups_group_visible($groupid, $course, $cm)) { | |
734 | throw new moodle_exception('notingroup'); | |
735 | } | |
736 | } else { | |
737 | $groupid = 0; | |
738 | } | |
739 | } | |
740 | ||
741 | if (!empty($params['advsearch'])) { | |
742 | $advanced = true; | |
743 | $defaults = []; | |
744 | $fn = $ln = ''; // Defaults for first and last name. | |
745 | // Force defaults for advanced search. | |
746 | foreach ($params['advsearch'] as $adv) { | |
8cc04bcc JL |
747 | if ($adv['name'] == 'fn') { |
748 | $fn = json_decode($adv['value']); | |
749 | continue; | |
750 | } | |
751 | if ($adv['name'] == 'ln') { | |
752 | $ln = json_decode($adv['value']); | |
56b8edcb JL |
753 | continue; |
754 | } | |
755 | $defaults[$adv['name']] = json_decode($adv['value']); | |
756 | } | |
757 | list($searcharray, $params['search']) = data_build_search_array($database, false, [], $defaults, $fn, $ln); | |
758 | } else { | |
759 | $advanced = null; | |
760 | $searcharray = null; | |
761 | } | |
762 | ||
763 | list($records, $maxcount, $totalcount, $page, $nowperpage, $sort, $mode) = | |
764 | data_search_entries($database, $cm, $context, 'list', $groupid, $params['search'], $params['sort'], $params['order'], | |
765 | $params['page'], $params['perpage'], $advanced, $searcharray); | |
766 | ||
767 | $entries = []; | |
768 | foreach ($records as $record) { | |
769 | $user = user_picture::unalias($record, null, 'userid'); | |
770 | $related = array('context' => $context, 'database' => $database, 'user' => $user); | |
771 | if ($params['returncontents']) { | |
772 | $related['contents'] = $DB->get_records('data_content', array('recordid' => $record->id)); | |
773 | } else { | |
774 | $related['contents'] = null; | |
775 | } | |
776 | ||
777 | $exporter = new record_exporter($record, $related); | |
778 | $entries[] = $exporter->export($PAGE->get_renderer('core')); | |
779 | } | |
780 | ||
781 | $result = array( | |
782 | 'entries' => $entries, | |
783 | 'totalcount' => $totalcount, | |
784 | 'maxcount' => $maxcount, | |
785 | 'warnings' => $warnings | |
786 | ); | |
787 | ||
788 | // Check if we should return the list rendered. | |
789 | if ($params['returncontents']) { | |
790 | ob_start(); | |
791 | // The return parameter stops the execution after the first record. | |
792 | data_print_template('listtemplate', $records, $database, '', $page, false); | |
793 | $result['listviewcontents'] = ob_get_contents(); | |
794 | ob_end_clean(); | |
795 | } | |
796 | ||
797 | return $result; | |
798 | } | |
799 | ||
800 | /** | |
801 | * Returns description of method result value | |
802 | * | |
803 | * @return external_description | |
804 | * @since Moodle 3.3 | |
805 | */ | |
806 | public static function search_entries_returns() { | |
807 | return new external_single_structure( | |
808 | array( | |
809 | 'entries' => new external_multiple_structure( | |
810 | record_exporter::get_read_structure() | |
811 | ), | |
be4bdab7 JL |
812 | 'totalcount' => new external_value(PARAM_INT, 'Total count of records returned by the search.'), |
813 | 'maxcount' => new external_value(PARAM_INT, 'Total count of records that the user could see in the database | |
814 | (if all the search criterias were removed).', VALUE_OPTIONAL), | |
56b8edcb JL |
815 | 'listviewcontents' => new external_value(PARAM_RAW, 'The list view contents as is rendered in the site.', |
816 | VALUE_OPTIONAL), | |
817 | 'warnings' => new external_warnings() | |
818 | ) | |
819 | ); | |
820 | } | |
229158fe JL |
821 | |
822 | /** | |
823 | * Returns description of method parameters | |
824 | * | |
825 | * @return external_function_parameters | |
826 | * @since Moodle 3.3 | |
827 | */ | |
828 | public static function approve_entry_parameters() { | |
829 | return new external_function_parameters( | |
830 | array( | |
831 | 'entryid' => new external_value(PARAM_INT, 'Record entry id.'), | |
832 | 'approve' => new external_value(PARAM_BOOL, 'Whether to approve (true) or unapprove the entry.', | |
833 | VALUE_DEFAULT, true), | |
834 | ) | |
835 | ); | |
836 | } | |
837 | ||
838 | /** | |
839 | * Approves or unapproves an entry. | |
840 | * | |
841 | * @param int $entryid the record entry id id | |
842 | * @param bool $approve whether to approve (true) or unapprove the entry | |
843 | * @return array of warnings and the entries | |
844 | * @since Moodle 3.3 | |
845 | * @throws moodle_exception | |
846 | */ | |
847 | public static function approve_entry($entryid, $approve = true) { | |
848 | global $PAGE, $DB; | |
849 | ||
850 | $params = array('entryid' => $entryid, 'approve' => $approve); | |
851 | $params = self::validate_parameters(self::approve_entry_parameters(), $params); | |
852 | $warnings = array(); | |
853 | ||
854 | $record = $DB->get_record('data_records', array('id' => $params['entryid']), '*', MUST_EXIST); | |
855 | list($database, $course, $cm, $context) = self::validate_database($record->dataid); | |
856 | // Check database is open in time. | |
857 | data_require_time_available($database, null, $context); | |
858 | // Check specific capabilities. | |
859 | require_capability('mod/data:approve', $context); | |
860 | ||
861 | data_approve_entry($record->id, $params['approve']); | |
862 | ||
863 | $result = array( | |
864 | 'status' => true, | |
865 | 'warnings' => $warnings | |
866 | ); | |
867 | return $result; | |
868 | } | |
869 | ||
870 | /** | |
871 | * Returns description of method result value | |
872 | * | |
873 | * @return external_description | |
874 | * @since Moodle 3.3 | |
875 | */ | |
876 | public static function approve_entry_returns() { | |
877 | return new external_single_structure( | |
878 | array( | |
879 | 'status' => new external_value(PARAM_BOOL, 'status: true if success'), | |
880 | 'warnings' => new external_warnings() | |
881 | ) | |
882 | ); | |
883 | } | |
67bb168e JL |
884 | |
885 | /** | |
886 | * Returns description of method parameters | |
887 | * | |
888 | * @return external_function_parameters | |
889 | * @since Moodle 3.3 | |
890 | */ | |
891 | public static function delete_entry_parameters() { | |
892 | return new external_function_parameters( | |
893 | array( | |
894 | 'entryid' => new external_value(PARAM_INT, 'Record entry id.'), | |
895 | ) | |
896 | ); | |
897 | } | |
898 | ||
899 | /** | |
900 | * Deletes an entry. | |
901 | * | |
902 | * @param int $entryid the record entry id | |
903 | * @return array of warnings success status | |
904 | * @since Moodle 3.3 | |
905 | * @throws moodle_exception | |
906 | */ | |
907 | public static function delete_entry($entryid) { | |
908 | global $PAGE, $DB; | |
909 | ||
910 | $params = array('entryid' => $entryid); | |
911 | $params = self::validate_parameters(self::delete_entry_parameters(), $params); | |
912 | $warnings = array(); | |
913 | ||
914 | $record = $DB->get_record('data_records', array('id' => $params['entryid']), '*', MUST_EXIST); | |
915 | list($database, $course, $cm, $context) = self::validate_database($record->dataid); | |
916 | ||
917 | if (data_user_can_manage_entry($record, $database, $context)) { | |
918 | data_delete_record($record->id, $database, $course->id, $cm->id); | |
919 | } else { | |
920 | throw new moodle_exception('noaccess', 'data'); | |
921 | } | |
922 | ||
923 | $result = array( | |
924 | 'status' => true, | |
925 | 'warnings' => $warnings | |
926 | ); | |
927 | return $result; | |
928 | } | |
929 | ||
930 | /** | |
931 | * Returns description of method result value | |
932 | * | |
933 | * @return external_description | |
934 | * @since Moodle 3.3 | |
935 | */ | |
936 | public static function delete_entry_returns() { | |
937 | return new external_single_structure( | |
938 | array( | |
939 | 'status' => new external_value(PARAM_BOOL, 'Always true. If we see this field it means that the entry was deleted.'), | |
940 | 'warnings' => new external_warnings() | |
941 | ) | |
942 | ); | |
943 | } | |
61c640c1 JL |
944 | |
945 | /** | |
946 | * Returns description of method parameters | |
947 | * | |
948 | * @return external_function_parameters | |
949 | * @since Moodle 3.3 | |
950 | */ | |
951 | public static function add_entry_parameters() { | |
952 | return new external_function_parameters( | |
953 | array( | |
954 | 'databaseid' => new external_value(PARAM_INT, 'data instance id'), | |
955 | 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', | |
956 | VALUE_DEFAULT, 0), | |
957 | 'data' => new external_multiple_structure( | |
958 | new external_single_structure( | |
959 | array( | |
960 | 'fieldid' => new external_value(PARAM_INT, 'The field id.'), | |
961 | 'subfield' => new external_value(PARAM_NOTAGS, 'The subfield name (if required).', VALUE_DEFAULT, ''), | |
962 | 'value' => new external_value(PARAM_RAW, 'The contents for the field always JSON encoded.'), | |
963 | ) | |
964 | ), 'The fields data to be created' | |
965 | ), | |
966 | ) | |
967 | ); | |
968 | } | |
969 | ||
970 | /** | |
971 | * Adds a new entry to a database | |
972 | * | |
973 | * @param int $databaseid the data instance id | |
974 | * @param int $groupid (optional) group id, 0 means that the function will determine the user group | |
975 | * @param array $data the fields data to be created | |
976 | * @return array of warnings and status result | |
977 | * @since Moodle 3.3 | |
978 | * @throws moodle_exception | |
979 | */ | |
980 | public static function add_entry($databaseid, $groupid, $data) { | |
981 | global $DB; | |
982 | ||
983 | $params = array('databaseid' => $databaseid, 'groupid' => $groupid, 'data' => $data); | |
984 | $params = self::validate_parameters(self::add_entry_parameters(), $params); | |
985 | $warnings = array(); | |
986 | $fieldnotifications = array(); | |
987 | ||
988 | list($database, $course, $cm, $context) = self::validate_database($params['databaseid']); | |
989 | // Check database is open in time. | |
990 | data_require_time_available($database, null, $context); | |
991 | ||
992 | $groupmode = groups_get_activity_groupmode($cm); | |
993 | if (!empty($params['groupid'])) { | |
994 | $groupid = $params['groupid']; | |
995 | // Determine is the group is visible to user. | |
996 | if (!groups_group_visible($groupid, $course, $cm)) { | |
997 | throw new moodle_exception('notingroup'); | |
998 | } | |
999 | } else { | |
1000 | // Check to see if groups are being used here. | |
1001 | if ($groupmode) { | |
1002 | $groupid = groups_get_activity_group($cm); | |
1003 | // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). | |
1004 | if (!groups_group_visible($groupid, $course, $cm)) { | |
1005 | throw new moodle_exception('notingroup'); | |
1006 | } | |
1007 | } else { | |
1008 | $groupid = 0; | |
1009 | } | |
1010 | } | |
1011 | ||
1012 | if (!data_user_can_add_entry($database, $groupid, $groupmode, $context)) { | |
1013 | throw new moodle_exception('noaccess', 'data'); | |
1014 | } | |
1015 | ||
1016 | // Prepare the data as is expected by the API. | |
1017 | $datarecord = new stdClass; | |
1018 | foreach ($params['data'] as $data) { | |
1019 | $subfield = ($data['subfield'] !== '') ? '_' . $data['subfield'] : ''; | |
1020 | // We ask for JSON encoded values because of multiple choice forms or checkboxes that use array parameters. | |
1021 | $datarecord->{'field_' . $data['fieldid'] . $subfield} = json_decode($data['value']); | |
1022 | } | |
1023 | // Validate to ensure that enough data was submitted. | |
1024 | $fields = $DB->get_records('data_fields', array('dataid' => $database->id)); | |
1025 | $processeddata = data_process_submission($database, $fields, $datarecord); | |
1026 | ||
1027 | // Format notifications. | |
1028 | if (!empty($processeddata->fieldnotifications)) { | |
1029 | foreach ($processeddata->fieldnotifications as $field => $notififications) { | |
1030 | foreach ($notififications as $notif) { | |
1031 | $fieldnotifications[] = [ | |
1032 | 'fieldname' => $field, | |
1033 | 'notification' => $notif, | |
1034 | ]; | |
1035 | } | |
1036 | } | |
1037 | } | |
1038 | ||
1039 | // Create a new (empty) record. | |
1040 | $newentryid = 0; | |
1041 | if ($processeddata->validated && $recordid = data_add_record($database, $groupid)) { | |
1042 | $newentryid = $recordid; | |
1043 | // Now populate the fields contents of the new record. | |
1044 | data_add_fields_contents_to_new_record($database, $context, $recordid, $fields, $datarecord, $processeddata); | |
1045 | } | |
1046 | ||
1047 | $result = array( | |
1048 | 'newentryid' => $newentryid, | |
1049 | 'generalnotifications' => $processeddata->generalnotifications, | |
1050 | 'fieldnotifications' => $fieldnotifications, | |
1051 | ); | |
1052 | return $result; | |
1053 | } | |
1054 | ||
1055 | /** | |
1056 | * Returns description of method result value | |
1057 | * | |
1058 | * @return external_description | |
1059 | * @since Moodle 3.3 | |
1060 | */ | |
1061 | public static function add_entry_returns() { | |
1062 | return new external_single_structure( | |
1063 | array( | |
1064 | 'newentryid' => new external_value(PARAM_INT, 'True new created entry id. 0 if the entry was not created.'), | |
1065 | 'generalnotifications' => new external_multiple_structure( | |
1066 | new external_value(PARAM_RAW, 'General notifications') | |
1067 | ), | |
1068 | 'fieldnotifications' => new external_multiple_structure( | |
1069 | new external_single_structure( | |
1070 | array( | |
1071 | 'fieldname' => new external_value(PARAM_TEXT, 'The field name.'), | |
1072 | 'notification' => new external_value(PARAM_RAW, 'The notification for the field.'), | |
1073 | ) | |
1074 | ) | |
1075 | ), | |
1076 | 'warnings' => new external_warnings() | |
1077 | ) | |
1078 | ); | |
1079 | } | |
4ca2890d JL |
1080 | |
1081 | /** | |
1082 | * Returns description of method parameters | |
1083 | * | |
1084 | * @return external_function_parameters | |
1085 | * @since Moodle 3.3 | |
1086 | */ | |
1087 | public static function update_entry_parameters() { | |
1088 | return new external_function_parameters( | |
1089 | array( | |
1090 | 'entryid' => new external_value(PARAM_INT, 'The entry record id.'), | |
1091 | 'data' => new external_multiple_structure( | |
1092 | new external_single_structure( | |
1093 | array( | |
1094 | 'fieldid' => new external_value(PARAM_INT, 'The field id.'), | |
1095 | 'subfield' => new external_value(PARAM_NOTAGS, 'The subfield name (if required).', VALUE_DEFAULT, null), | |
1096 | 'value' => new external_value(PARAM_RAW, 'The new contents for the field always JSON encoded.'), | |
1097 | ) | |
1098 | ), 'The fields data to be updated' | |
1099 | ), | |
1100 | ) | |
1101 | ); | |
1102 | } | |
1103 | ||
1104 | /** | |
1105 | * Updates an existing entry. | |
1106 | * | |
1107 | * @param int $entryid the data instance id | |
1108 | * @param array $data the fields data to be created | |
1109 | * @return array of warnings and status result | |
1110 | * @since Moodle 3.3 | |
1111 | * @throws moodle_exception | |
1112 | */ | |
1113 | public static function update_entry($entryid, $data) { | |
1114 | global $DB; | |
1115 | ||
1116 | $params = array('entryid' => $entryid, 'data' => $data); | |
1117 | $params = self::validate_parameters(self::update_entry_parameters(), $params); | |
1118 | $warnings = array(); | |
1119 | $fieldnotifications = array(); | |
1120 | $updated = false; | |
1121 | ||
1122 | $record = $DB->get_record('data_records', array('id' => $params['entryid']), '*', MUST_EXIST); | |
1123 | list($database, $course, $cm, $context) = self::validate_database($record->dataid); | |
1124 | // Check database is open in time. | |
1125 | data_require_time_available($database, null, $context); | |
1126 | ||
1127 | if (!data_user_can_manage_entry($record, $database, $context)) { | |
1128 | throw new moodle_exception('noaccess', 'data'); | |
1129 | } | |
1130 | ||
1131 | // Prepare the data as is expected by the API. | |
1132 | $datarecord = new stdClass; | |
1133 | foreach ($params['data'] as $data) { | |
1134 | $subfield = ($data['subfield'] !== '') ? '_' . $data['subfield'] : ''; | |
1135 | // We ask for JSON encoded values because of multiple choice forms or checkboxes that use array parameters. | |
1136 | $datarecord->{'field_' . $data['fieldid'] . $subfield} = json_decode($data['value']); | |
1137 | } | |
1138 | // Validate to ensure that enough data was submitted. | |
1139 | $fields = $DB->get_records('data_fields', array('dataid' => $database->id)); | |
1140 | $processeddata = data_process_submission($database, $fields, $datarecord); | |
1141 | ||
1142 | // Format notifications. | |
1143 | if (!empty($processeddata->fieldnotifications)) { | |
1144 | foreach ($processeddata->fieldnotifications as $field => $notififications) { | |
1145 | foreach ($notififications as $notif) { | |
1146 | $fieldnotifications[] = [ | |
1147 | 'fieldname' => $field, | |
1148 | 'notification' => $notif, | |
1149 | ]; | |
1150 | } | |
1151 | } | |
1152 | } | |
1153 | ||
1154 | if ($processeddata->validated) { | |
1155 | // Now update the fields contents. | |
1156 | data_update_record_fields_contents($database, $record, $context, $datarecord, $processeddata); | |
1157 | $updated = true; | |
1158 | } | |
1159 | ||
1160 | $result = array( | |
1161 | 'updated' => $updated, | |
1162 | 'generalnotifications' => $processeddata->generalnotifications, | |
1163 | 'fieldnotifications' => $fieldnotifications, | |
1164 | 'warnings' => $warnings, | |
1165 | ); | |
1166 | return $result; | |
1167 | } | |
1168 | ||
1169 | /** | |
1170 | * Returns description of method result value | |
1171 | * | |
1172 | * @return external_description | |
1173 | * @since Moodle 3.3 | |
1174 | */ | |
1175 | public static function update_entry_returns() { | |
1176 | return new external_single_structure( | |
1177 | array( | |
1178 | 'updated' => new external_value(PARAM_BOOL, 'True if the entry was successfully updated, false other wise.'), | |
1179 | 'generalnotifications' => new external_multiple_structure( | |
1180 | new external_value(PARAM_RAW, 'General notifications') | |
1181 | ), | |
1182 | 'fieldnotifications' => new external_multiple_structure( | |
1183 | new external_single_structure( | |
1184 | array( | |
1185 | 'fieldname' => new external_value(PARAM_TEXT, 'The field name.'), | |
1186 | 'notification' => new external_value(PARAM_RAW, 'The notification for the field.'), | |
1187 | ) | |
1188 | ) | |
1189 | ), | |
1190 | 'warnings' => new external_warnings() | |
1191 | ) | |
1192 | ); | |
1193 | } | |
2ab34819 | 1194 | } |