MDL-49231 mod_glossary: External function get_entries_by_search
[moodle.git] / mod / glossary / classes / external.php
CommitLineData
23da998f
CC
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/>.
bf5bbe01 16
23da998f 17/**
bf5bbe01 18 * Glossary module external API.
23da998f
CC
19 *
20 * @package mod_glossary
21 * @category external
22 * @copyright 2015 Costantino Cito <ccito@cvaconsulting.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
bf5bbe01 24 * @since Moodle 3.1
23da998f 25 */
d0d4372c
FM
26
27defined('MOODLE_INTERNAL') || die();
28
bf5bbe01 29require_once($CFG->libdir . '/externallib.php');
d0d4372c 30require_once($CFG->dirroot . '/mod/glossary/lib.php');
bf5bbe01 31
23da998f 32/**
bf5bbe01 33 * Glossary module external functions.
23da998f
CC
34 *
35 * @package mod_glossary
36 * @category external
37 * @copyright 2015 Costantino Cito <ccito@cvaconsulting.com>
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
bf5bbe01 39 * @since Moodle 3.1
23da998f
CC
40 */
41class mod_glossary_external extends external_api {
bf5bbe01 42
fe11f9a4
FM
43 /**
44 * Get the browse modes from the display format.
45 *
46 * This returns some of the terms that can be used when reporting a glossary being viewed.
47 *
48 * @param string $format The display format of the glossary.
49 * @return array Containing some of all of the following: letter, cat, date, author.
50 */
51 public static function get_browse_modes_from_display_format($format) {
52 global $DB;
53
54 $dp = $DB->get_record('glossary_formats', array('name' => $format), '*', IGNORE_MISSING);
55 $formats = glossary_get_visible_tabs($dp);
56
57 // Always add 'letter'.
58 $modes = array('letter');
59
60 if (in_array('category', $formats)) {
61 $modes[] = 'cat';
62 }
63 if (in_array('date', $formats)) {
64 $modes[] = 'date';
65 }
66 if (in_array('author', $formats)) {
67 $modes[] = 'author';
68 }
69
70 return $modes;
71 }
72
73 /**
74 * Get the return value of an entry.
75 *
9cafa794 76 * @param bool $includecat Whether the definition should include category info.
fe11f9a4
FM
77 * @return external_definition
78 */
9cafa794
FM
79 public static function get_entry_return_structure($includecat = false) {
80 $params = array(
fe11f9a4
FM
81 'id' => new external_value(PARAM_INT, 'The entry ID'),
82 'glossaryid' => new external_value(PARAM_INT, 'The glossary ID'),
83 'userid' => new external_value(PARAM_INT, 'Author ID'),
84 'userfullname' => new external_value(PARAM_TEXT, 'Author full name'),
85 'userpictureurl' => new external_value(PARAM_URL, 'Author picture'),
86 'concept' => new external_value(PARAM_RAW, 'The concept'),
87 'definition' => new external_value(PARAM_RAW, 'The definition'),
88 'definitionformat' => new external_format_value('definition'),
89 'definitiontrust' => new external_value(PARAM_BOOL, 'The definition trust flag'),
90 'attachment' => new external_value(PARAM_BOOL, 'Whether or not the entry has attachments'),
91 'attachments' => new external_multiple_structure(
92 new external_single_structure(array(
93 'filename' => new external_value(PARAM_FILE, 'File name'),
94 'mimetype' => new external_value(PARAM_RAW, 'Mime type'),
95 'fileurl' => new external_value(PARAM_URL, 'File download URL')
96 )), 'attachments', VALUE_OPTIONAL
97 ),
98 'timecreated' => new external_value(PARAM_INT, 'Time created'),
99 'timemodified' => new external_value(PARAM_INT, 'Time modified'),
100 'teacherentry' => new external_value(PARAM_BOOL, 'The entry was created by a teacher, or equivalent.'),
101 'sourceglossaryid' => new external_value(PARAM_INT, 'The source glossary ID'),
102 'usedynalink' => new external_value(PARAM_BOOL, 'Whether the concept should be automatically linked'),
103 'casesensitive' => new external_value(PARAM_BOOL, 'When true, the matching is case sensitive'),
104 'fullmatch' => new external_value(PARAM_BOOL, 'When true, the matching is done on full words only'),
105 'approved' => new external_value(PARAM_BOOL, 'Whether the entry was approved'),
9cafa794
FM
106 );
107
108 if ($includecat) {
109 $params['categoryid'] = new external_value(PARAM_INT, 'The category ID. This may be' .
110 ' \''. GLOSSARY_SHOW_NOT_CATEGORISED . '\' when the entry is not categorised', VALUE_DEFAULT,
111 GLOSSARY_SHOW_NOT_CATEGORISED);
112 $params['categoryname'] = new external_value(PARAM_RAW, 'The category name. May be empty when the entry is' .
113 ' not categorised, or the request was limited to one category.', VALUE_DEFAULT, '');
114 }
115
116 return new external_single_structure($params);
fe11f9a4
FM
117 }
118
119 /**
120 * Fill in an entry object.
121 *
122 * This adds additional required fields for the external function to return.
123 *
124 * @param stdClass $entry The entry.
125 * @param context $context The context the entry belongs to.
126 * @return void
127 */
3bb15852 128 public static function fill_entry_details($entry, $context) {
fe11f9a4
FM
129 global $PAGE;
130 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
131
132 // Format concept and definition.
133 $entry->concept = external_format_string($entry->concept, $context->id);
134 list($entry->definition, $entry->definitionformat) = external_format_text($entry->definition, $entry->definitionformat,
135 $context->id, 'mod_glossary', 'entry', $entry->id);
136
137 // Author details.
3bb15852 138 $user = mod_glossary_entry_query_builder::get_user_from_record($entry);
fe11f9a4
FM
139 $userpicture = new user_picture($user);
140 $userpicture->size = 1;
141 $entry->userfullname = fullname($user, $canviewfullnames);
142 $entry->userpictureurl = $userpicture->get_url($PAGE)->out(false);
143
144 // Fetch attachments.
145 $entry->attachment = !empty($entry->attachment) ? 1 : 0;
146 $entry->attachments = array();
147 if ($entry->attachment) {
148 $fs = get_file_storage();
149 if ($files = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id, 'filename', false)) {
150 foreach ($files as $file) {
151 $filename = $file->get_filename();
152 $fileurl = moodle_url::make_webservice_pluginfile_url($context->id, 'mod_glossary', 'attachment',
153 $entry->id, '/', $filename);
154 $entry->attachments[] = array(
155 'filename' => $filename,
156 'mimetype' => $file->get_mimetype(),
157 'fileurl' => $fileurl->out(false)
158 );
159 }
160 }
161 }
162 }
163
21e30022
FM
164 /**
165 * Validate a glossary via ID.
166 *
167 * @param int $id The glossary ID.
168 * @return array Contains glossary, context, course and cm.
169 */
170 public static function validate_glossary($id) {
171 global $DB;
172 $glossary = $DB->get_record('glossary', array('id' => $id), '*', MUST_EXIST);
173 list($course, $cm) = get_course_and_cm_from_instance($glossary, 'glossary');
174 $context = context_module::instance($cm->id);
175 self::validate_context($context);
176 return array($glossary, $context, $course, $cm);
177 }
178
23da998f
CC
179 /**
180 * Describes the parameters for get_glossaries_by_courses.
181 *
182 * @return external_external_function_parameters
bf5bbe01 183 * @since Moodle 3.1
23da998f
CC
184 */
185 public static function get_glossaries_by_courses_parameters() {
186 return new external_function_parameters (
187 array(
188 'courseids' => new external_multiple_structure(
189 new external_value(PARAM_INT, 'course id'),
bf5bbe01 190 'Array of course IDs', VALUE_DEFAULT, array()
23da998f
CC
191 ),
192 )
193 );
194 }
bf5bbe01 195
23da998f 196 /**
bf5bbe01 197 * Returns a list of glossaries in a provided list of courses.
23da998f 198 *
bf5bbe01
FM
199 * If no list is provided all glossaries that the user can view will be returned.
200 *
201 * @param array $courseids the course IDs.
202 * @return array of glossaries
203 * @since Moodle 3.1
23da998f
CC
204 */
205 public static function get_glossaries_by_courses($courseids = array()) {
23da998f 206 $params = self::validate_parameters(self::get_glossaries_by_courses_parameters(), array('courseids' => $courseids));
bf5bbe01 207
23da998f 208 $warnings = array();
bf5bbe01
FM
209 $courses = array();
210 $courseids = $params['courseids'];
211
212 if (empty($courseids)) {
23da998f
CC
213 $courses = enrol_get_my_courses();
214 $courseids = array_keys($courses);
215 }
bf5bbe01 216
23da998f 217 // Array to store the glossaries to return.
bf5bbe01 218 $glossaries = array();
fe11f9a4 219 $modes = array();
bf5bbe01 220
23da998f
CC
221 // Ensure there are courseids to loop through.
222 if (!empty($courseids)) {
bf5bbe01
FM
223 list($courses, $warnings) = external_util::validate_courses($courseids, $courses);
224
225 // Get the glossaries in these courses, this function checks users visibility permissions.
226 $glossaries = get_all_instances_in_courses('glossary', $courses);
23da998f 227 foreach ($glossaries as $glossary) {
bf5bbe01
FM
228 $context = context_module::instance($glossary->coursemodule);
229 $glossary->name = external_format_string($glossary->name, $context->id);
230 list($glossary->intro, $glossary->introformat) = external_format_text($glossary->intro, $glossary->introformat,
231 $context->id, 'mod_glossary', 'intro', null);
fe11f9a4
FM
232
233 // Make sure we have a number of entries per page.
234 if (!$glossary->entbypage) {
235 $glossary->entbypage = $CFG->glossary_entbypage;
236 }
237
238 // Add the list of browsing modes.
239 if (!isset($modes[$glossary->displayformat])) {
240 $modes[$glossary->displayformat] = self::get_browse_modes_from_display_format($glossary->displayformat);
241 }
242 $glossary->browsemodes = $modes[$glossary->displayformat];
23da998f
CC
243 }
244 }
bf5bbe01 245
23da998f 246 $result = array();
bf5bbe01 247 $result['glossaries'] = $glossaries;
23da998f
CC
248 $result['warnings'] = $warnings;
249 return $result;
250 }
bf5bbe01 251
23da998f
CC
252 /**
253 * Describes the get_glossaries_by_courses return value.
254 *
255 * @return external_single_structure
bf5bbe01 256 * @since Moodle 3.1
23da998f
CC
257 */
258 public static function get_glossaries_by_courses_returns() {
bf5bbe01
FM
259 return new external_single_structure(array(
260 'glossaries' => new external_multiple_structure(
261 new external_single_structure(array(
262 'id' => new external_value(PARAM_INT, 'Glossary id'),
263 'coursemodule' => new external_value(PARAM_INT, 'Course module id'),
264 'course' => new external_value(PARAM_INT, 'Course id'),
265 'name' => new external_value(PARAM_RAW, 'Glossary name'),
266 'intro' => new external_value(PARAM_RAW, 'The Glossary intro'),
267 'introformat' => new external_format_value('intro'),
268 'allowduplicatedentries' => new external_value(PARAM_INT, 'If enabled, multiple entries can have the' .
269 ' same concept name'),
270 'displayformat' => new external_value(PARAM_TEXT, 'Display format type'),
271 'mainglossary' => new external_value(PARAM_INT, 'If enabled this glossary is a main glossary.'),
272 'showspecial' => new external_value(PARAM_INT, 'If enabled, participants can browse the glossary by' .
273 ' special characters, such as @ and #'),
274 'showalphabet' => new external_value(PARAM_INT, 'If enabled, participants can browse the glossary by' .
275 ' letters of the alphabet'),
276 'showall' => new external_value(PARAM_INT, 'If enabled, participants can browse all entries at once'),
277 'allowcomments' => new external_value(PARAM_INT, 'If enabled, all participants with permission to' .
278 ' create comments will be able to add comments to glossary entries'),
279 'allowprintview' => new external_value(PARAM_INT, 'If enabled, students are provided with a link to a' .
280 ' printer-friendly version of the glossary. The link is always available to teachers'),
281 'usedynalink' => new external_value(PARAM_INT, 'If site-wide glossary auto-linking has been enabled' .
282 ' by an administrator and this checkbox is ticked, the entry will be automatically linked' .
283 ' wherever the concept words and phrases appear throughout the rest of the course.'),
284 'defaultapproval' => new external_value(PARAM_INT, 'If set to no, entries require approving by a' .
285 ' teacher before they are viewable by everyone.'),
286 'approvaldisplayformat' => new external_value(PARAM_TEXT, 'When approving glossary items you may wish' .
287 ' to use a different display format'),
288 'globalglossary' => new external_value(PARAM_INT, ''),
289 'entbypage' => new external_value(PARAM_INT, 'Entries shown per page'),
290 'editalways' => new external_value(PARAM_INT, 'Always allow editing'),
291 'rsstype' => new external_value(PARAM_INT, 'To enable the RSS feed for this activity, select either' .
292 ' concepts with author or concepts without author to be included in the feed'),
293 'rssarticles' => new external_value(PARAM_INT, 'This setting specifies the number of glossary entry' .
294 ' concepts to include in the RSS feed. Between 5 and 20 generally acceptable'),
295 'assessed' => new external_value(PARAM_INT, 'Aggregate type'),
296 'assesstimestart' => new external_value(PARAM_INT, 'Restrict rating to items created after this'),
297 'assesstimefinish' => new external_value(PARAM_INT, 'Restrict rating to items created before this'),
298 'scale' => new external_value(PARAM_INT, 'Scale ID'),
299 'timecreated' => new external_value(PARAM_INT, 'Time created'),
300 'timemodified' => new external_value(PARAM_INT, 'Time modified'),
301 'completionentries' => new external_value(PARAM_INT, 'Number of entries to complete'),
302 'section' => new external_value(PARAM_INT, 'Section'),
303 'visible' => new external_value(PARAM_INT, 'Visible'),
304 'groupmode' => new external_value(PARAM_INT, 'Group mode'),
305 'groupingid' => new external_value(PARAM_INT, 'Grouping ID'),
fe11f9a4
FM
306 'browsemodes' => new external_multiple_structure(
307 new external_value(PARAM_ALPHA, 'Modes of browsing allowed')
308 )
bf5bbe01
FM
309 ), 'Glossaries')
310 ),
311 'warnings' => new external_warnings())
23da998f
CC
312 );
313 }
d0d4372c
FM
314
315 /**
316 * Returns the description of the external function parameters.
317 *
318 * @return external_function_parameters
319 * @since Moodle 3.1
320 */
321 public static function view_glossary_parameters() {
322 return new external_function_parameters(array(
323 'id' => new external_value(PARAM_INT, 'Glossary instance ID'),
324 'mode' => new external_value(PARAM_ALPHA, 'The mode in which the glossary is viewed'),
325 ));
326 }
327
328 /**
329 * Notify that the course module was viewed.
330 *
331 * @param int $id The glossary instance ID.
332 * @return array of warnings and status result
333 * @since Moodle 3.1
334 * @throws moodle_exception
335 */
336 public static function view_glossary($id, $mode) {
337 global $DB;
338
339 $params = self::validate_parameters(self::view_glossary_parameters(), array(
340 'id' => $id,
341 'mode' => $mode
342 ));
343 $id = $params['id'];
344 $mode = $params['mode'];
345 $warnings = array();
346
21e30022
FM
347 // Get and validate the glossary.
348 list($glossary, $context, $course, $cm) = self::validate_glossary($id);
d0d4372c
FM
349
350 // Trigger module viewed event.
351 glossary_view($glossary, $course, $cm, $context, $mode);
352
353 return array(
354 'status' => true,
355 'warnings' => $warnings
356 );
357 }
358
359 /**
360 * Returns the description of the external function return value.
361 *
362 * @return external_description
363 * @since Moodle 3.1
364 */
365 public static function view_glossary_returns() {
366 return new external_single_structure(array(
367 'status' => new external_value(PARAM_BOOL, 'True on success'),
368 'warnings' => new external_warnings()
369 ));
370 }
371
61fce284
FM
372 /**
373 * Returns the description of the external function parameters.
374 *
375 * @return external_function_parameters
376 * @since Moodle 3.1
377 */
378 public static function view_entry_parameters() {
379 return new external_function_parameters(array(
380 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
381 ));
382 }
383
384 /**
385 * Notify that the entry was viewed.
386 *
387 * @param int $id The entry ID.
388 * @return array of warnings and status result
389 * @since Moodle 3.1
390 * @throws moodle_exception
391 */
392 public static function view_entry($id) {
393 global $DB, $USER;
394
395 $params = self::validate_parameters(self::view_entry_parameters(), array('id' => $id));
396 $id = $params['id'];
397 $warnings = array();
398
21e30022 399 // Get and validate the glossary.
61fce284 400 $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST);
21e30022 401 list($glossary, $context) = self::validate_glossary($entry->glossaryid);
61fce284
FM
402
403 if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) {
404 throw new invalid_parameter_exception('invalidentry');
405 }
406
407 // Trigger view.
408 glossary_entry_view($entry, $context);
409
410 return array(
411 'status' => true,
412 'warnings' => $warnings
413 );
414 }
415
416 /**
417 * Returns the description of the external function return value.
418 *
419 * @return external_description
420 * @since Moodle 3.1
421 */
422 public static function view_entry_returns() {
423 return new external_single_structure(array(
424 'status' => new external_value(PARAM_BOOL, 'True on success'),
425 'warnings' => new external_warnings()
426 ));
427 }
428
fe11f9a4
FM
429 /**
430 * Returns the description of the external function parameters.
431 *
432 * @return external_function_parameters
433 * @since Moodle 3.1
434 */
435 public static function get_entries_by_letter_parameters() {
436 return new external_function_parameters(array(
437 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
438 'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
439 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
440 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
441 'options' => new external_single_structure(array(
442 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
443 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
444 ), 'An array of options', VALUE_DEFAULT, array())
445 ));
446 }
447
448 /**
449 * Browse a glossary entries by letter.
450 *
451 * @param int $id The glossary ID.
452 * @param string $letter A letter, or a special keyword.
453 * @param int $from Start returning records from here.
454 * @param int $limit Number of records to return.
455 * @param array $options Array of options.
456 * @return array of warnings and status result
457 * @since Moodle 3.1
458 * @throws moodle_exception
459 */
460 public static function get_entries_by_letter($id, $letter, $from = 0, $limit = 20, $options = array()) {
461 global $DB, $USER;
462
463 $params = self::validate_parameters(self::get_entries_by_letter_parameters(), array(
464 'id' => $id,
465 'letter' => $letter,
466 'from' => $from,
467 'limit' => $limit,
468 'options' => $options,
469 ));
470 $id = $params['id'];
471 $letter = $params['letter'];
472 $from = $params['from'];
473 $limit = $params['limit'];
474 $options = $params['options'];
475 $warnings = array();
476
21e30022
FM
477 // Get and validate the glossary.
478 list($glossary, $context) = self::validate_glossary($id);
fe11f9a4
FM
479
480 // Validate the mode.
481 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
482 if (!in_array('letter', $modes)) {
483 throw new invalid_parameter_exception('invalidbrowsemode');
484 }
485
8382bb4e
FM
486 $entries = array();
487 list($records, $count) = glossary_get_entries_by_letter($glossary, $context, $letter, $from, $limit, $options);
488 foreach ($records as $key => $record) {
489 self::fill_entry_details($record, $context);
490 $entries[] = $record;
fe11f9a4 491 }
8382bb4e 492 $records->close();
fe11f9a4
FM
493
494 return array(
495 'count' => $count,
496 'entries' => $entries,
497 'warnings' => $warnings
498 );
499 }
500
501 /**
502 * Returns the description of the external function return value.
503 *
504 * @return external_description
505 * @since Moodle 3.1
506 */
507 public static function get_entries_by_letter_returns() {
508 return new external_single_structure(array(
509 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
510 'entries' => new external_multiple_structure(
511 self::get_entry_return_structure()
512 ),
513 'warnings' => new external_warnings()
514 ));
515 }
6a273d5a
FM
516
517 /**
518 * Returns the description of the external function parameters.
519 *
520 * @return external_function_parameters
521 * @since Moodle 3.1
522 */
523 public static function get_entries_by_date_parameters() {
524 return new external_function_parameters(array(
525 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
526 'order' => new external_value(PARAM_ALPHA, 'Order the records by: \'CREATION\' or \'UPDATE\'.',
527 VALUE_DEFAULT, 'UPDATE'),
528 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'DESC'),
529 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
530 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
531 'options' => new external_single_structure(array(
532 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
533 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
534 ), 'An array of options', VALUE_DEFAULT, array())
535 ));
536 }
537
538 /**
539 * Browse a glossary entries by date.
540 *
541 * @param int $id The glossary ID.
542 * @param string $order The way to order the records.
543 * @param string $sort The direction of the order.
544 * @param int $from Start returning records from here.
545 * @param int $limit Number of records to return.
546 * @param array $options Array of options.
547 * @return array of warnings and status result
548 * @since Moodle 3.1
549 * @throws moodle_exception
550 */
551 public static function get_entries_by_date($id, $order = 'UPDATE', $sort = 'DESC', $from = 0, $limit = 20,
552 $options = array()) {
553 global $DB, $USER;
554
555 $params = self::validate_parameters(self::get_entries_by_date_parameters(), array(
556 'id' => $id,
557 'order' => core_text::strtoupper($order),
558 'sort' => core_text::strtoupper($sort),
559 'from' => $from,
560 'limit' => $limit,
561 'options' => $options,
562 ));
563 $id = $params['id'];
564 $order = $params['order'];
565 $sort = $params['sort'];
566 $from = $params['from'];
567 $limit = $params['limit'];
568 $options = $params['options'];
569 $warnings = array();
570
571 if (!in_array($order, array('CREATION', 'UPDATE'))) {
572 throw new invalid_parameter_exception('invalidorder');
573 } else if (!in_array($sort, array('ASC', 'DESC'))) {
574 throw new invalid_parameter_exception('invalidsort');
575 }
576
21e30022
FM
577 // Get and validate the glossary.
578 list($glossary, $context) = self::validate_glossary($id);
6a273d5a
FM
579
580 // Validate the mode.
581 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
582 if (!in_array('date', $modes)) {
583 throw new invalid_parameter_exception('invalidbrowsemode');
584 }
585
8382bb4e
FM
586 $entries = array();
587 list($records, $count) = glossary_get_entries_by_date($glossary, $context, $order, $sort, $from, $limit, $options);
588 foreach ($records as $key => $record) {
589 self::fill_entry_details($record, $context);
590 $entries[] = $record;
6a273d5a 591 }
8382bb4e 592 $records->close();
6a273d5a
FM
593
594 return array(
595 'count' => $count,
596 'entries' => $entries,
597 'warnings' => $warnings
598 );
599 }
600
601 /**
602 * Returns the description of the external function return value.
603 *
604 * @return external_description
605 * @since Moodle 3.1
606 */
607 public static function get_entries_by_date_returns() {
608 return new external_single_structure(array(
609 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
610 'entries' => new external_multiple_structure(
611 self::get_entry_return_structure()
612 ),
613 'warnings' => new external_warnings()
614 ));
615 }
616
efb7a0a9
FM
617 /**
618 * Returns the description of the external function parameters.
619 *
620 * @return external_function_parameters
621 * @since Moodle 3.1
622 */
623 public static function get_categories_parameters() {
624 return new external_function_parameters(array(
625 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
626 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
627 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20)
628 ));
629 }
630
631 /**
632 * Get the categories of a glossary.
633 *
634 * @param int $id The glossary ID.
635 * @param int $from Start returning records from here.
636 * @param int $limit Number of records to return.
637 * @return array of warnings and status result
638 * @since Moodle 3.1
639 * @throws moodle_exception
640 */
641 public static function get_categories($id, $from = 0, $limit = 20) {
642 global $DB;
643
644 $params = self::validate_parameters(self::get_categories_parameters(), array(
645 'id' => $id,
646 'from' => $from,
647 'limit' => $limit
648 ));
649 $id = $params['id'];
650 $from = $params['from'];
651 $limit = $params['limit'];
652 $warnings = array();
653
21e30022
FM
654 // Get and validate the glossary.
655 list($glossary, $context) = self::validate_glossary($id);
efb7a0a9
FM
656
657 // Fetch the categories.
8382bb4e
FM
658 $categories = array();
659 list($records, $count) = glossary_get_categories($glossary, $from, $limit);
660 foreach ($records as $category) {
efb7a0a9 661 $category->name = external_format_string($category->name, $context->id);
8382bb4e 662 $categories[] = $category;
efb7a0a9
FM
663 }
664
665 return array(
666 'count' => $count,
667 'categories' => $categories,
668 'warnings' => array(),
669 );
670 }
671
672 /**
673 * Returns the description of the external function return value.
674 *
675 * @return external_description
676 * @since Moodle 3.1
677 */
678 public static function get_categories_returns() {
679 return new external_single_structure(array(
680 'count' => new external_value(PARAM_INT, 'The total number of records.'),
681 'categories' => new external_multiple_structure(
682 new external_single_structure(array(
683 'id' => new external_value(PARAM_INT, 'The category ID'),
684 'glossaryid' => new external_value(PARAM_INT, 'The glossary ID'),
685 'name' => new external_value(PARAM_RAW, 'The name of the category'),
686 'usedynalink' => new external_value(PARAM_BOOL, 'Whether the category is automatically linked'),
687 ))
688 ),
689 'warnings' => new external_warnings()
690 ));
691 }
692
9cafa794
FM
693 /**
694 * Returns the description of the external function parameters.
695 *
696 * @return external_function_parameters
697 * @since Moodle 3.1
698 */
699 public static function get_entries_by_category_parameters() {
700 return new external_function_parameters(array(
701 'id' => new external_value(PARAM_INT, 'Glossary entry ID.'),
702 'categoryid' => new external_value(PARAM_INT, 'The category ID. Use \'' . GLOSSARY_SHOW_ALL_CATEGORIES . '\' for all' .
703 ' categories, or \'' . GLOSSARY_SHOW_NOT_CATEGORISED . '\' for uncategorised entries.'),
704 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
705 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
706 'options' => new external_single_structure(array(
707 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
708 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
709 ), 'An array of options', VALUE_DEFAULT, array())
710 ));
711 }
712
713 /**
714 * Browse a glossary entries by category.
715 *
716 * @param int $id The glossary ID.
717 * @param int $categoryid The category ID.
718 * @param int $from Start returning records from here.
719 * @param int $limit Number of records to return.
720 * @param array $options Array of options.
721 * @return array of warnings and status result
722 * @since Moodle 3.1
723 * @throws moodle_exception
724 */
725 public static function get_entries_by_category($id, $categoryid, $from = 0, $limit = 20, $options = array()) {
726 global $DB, $USER;
727
728 $params = self::validate_parameters(self::get_entries_by_category_parameters(), array(
729 'id' => $id,
730 'categoryid' => $categoryid,
731 'from' => $from,
732 'limit' => $limit,
733 'options' => $options,
734 ));
735 $id = $params['id'];
736 $categoryid = $params['categoryid'];
737 $from = $params['from'];
738 $limit = $params['limit'];
739 $options = $params['options'];
740 $warnings = array();
741
21e30022
FM
742 // Get and validate the glossary.
743 list($glossary, $context) = self::validate_glossary($id);
9cafa794
FM
744
745 // Validate the mode.
746 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
747 if (!in_array('cat', $modes)) {
748 throw new invalid_parameter_exception('invalidbrowsemode');
749 }
750
751 // Validate the category.
752 if (in_array($categoryid, array(GLOSSARY_SHOW_ALL_CATEGORIES, GLOSSARY_SHOW_NOT_CATEGORISED))) {
753 // All good.
754 } else if ($DB->count_records('glossary_categories', array('id' => $categoryid, 'glossaryid' => $id)) < 1) {
755 throw new invalid_parameter_exception('invalidcategory');
756 }
757
9cafa794 758 // Fetching the entries.
8382bb4e
FM
759 $entries = array();
760 list($records, $count) = glossary_get_entries_by_category($glossary, $context, $categoryid, $from, $limit, $options);
761 foreach ($records as $key => $record) {
762 self::fill_entry_details($record, $context);
763 if ($record->categoryid === null) {
764 $record->categoryid = GLOSSARY_SHOW_NOT_CATEGORISED;
9cafa794 765 }
8382bb4e
FM
766 if (isset($record->categoryname)) {
767 $record->categoryname = external_format_string($record->categoryname, $context->id);
9cafa794 768 }
8382bb4e 769 $entries[] = $record;
9cafa794 770 }
8382bb4e 771 $records->close();
9cafa794
FM
772
773 return array(
774 'count' => $count,
775 'entries' => $entries,
776 'warnings' => $warnings
777 );
778 }
779
780 /**
781 * Returns the description of the external function return value.
782 *
783 * @return external_description
784 * @since Moodle 3.1
785 */
786 public static function get_entries_by_category_returns() {
787 return new external_single_structure(array(
788 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
789 'entries' => new external_multiple_structure(
790 self::get_entry_return_structure(true)
791 ),
792 'warnings' => new external_warnings()
793 ));
794 }
06c8bd22
FM
795
796 /**
797 * Returns the description of the external function parameters.
798 *
799 * @return external_function_parameters
800 * @since Moodle 3.1
801 */
802 public static function get_authors_parameters() {
803 return new external_function_parameters(array(
804 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
805 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
806 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
807 'options' => new external_single_structure(array(
808 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes self even if all of their entries' .
809 ' require approval. When true, also includes authors only having entries pending approval.', VALUE_DEFAULT, 0)
810 ), 'An array of options', VALUE_DEFAULT, array())
811 ));
812 }
813
814 /**
815 * Get the authors of a glossary.
816 *
817 * @param int $id The glossary ID.
818 * @param int $from Start returning records from here.
819 * @param int $limit Number of records to return.
820 * @param array $options Array of options.
821 * @return array of warnings and status result
822 * @since Moodle 3.1
823 * @throws moodle_exception
824 */
825 public static function get_authors($id, $from = 0, $limit = 20, $options = array()) {
826 global $DB, $PAGE, $USER;
827
828 $params = self::validate_parameters(self::get_authors_parameters(), array(
829 'id' => $id,
830 'from' => $from,
831 'limit' => $limit,
832 'options' => $options,
833 ));
834 $id = $params['id'];
835 $from = $params['from'];
836 $limit = $params['limit'];
837 $options = $params['options'];
838 $warnings = array();
839
21e30022
FM
840 // Get and validate the glossary.
841 list($glossary, $context) = self::validate_glossary($id);
06c8bd22 842
8382bb4e
FM
843 // Fetching the entries.
844 list($users, $count) = glossary_get_authors($glossary, $context, $limit, $from, $options);
06c8bd22
FM
845
846 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
06c8bd22
FM
847 foreach ($users as $user) {
848 $userpicture = new user_picture($user);
849 $userpicture->size = 1;
850
851 $author = new stdClass();
852 $author->id = $user->id;
853 $author->fullname = fullname($user, $canviewfullnames);
854 $author->pictureurl = $userpicture->get_url($PAGE)->out(false);
855 $authors[] = $author;
856 }
857 $users->close();
858
859 return array(
860 'count' => $count,
861 'authors' => $authors,
862 'warnings' => array(),
863 );
864 }
865
866 /**
867 * Returns the description of the external function return value.
868 *
869 * @return external_description
870 * @since Moodle 3.1
871 */
872 public static function get_authors_returns() {
873 return new external_single_structure(array(
874 'count' => new external_value(PARAM_INT, 'The total number of records.'),
875 'authors' => new external_multiple_structure(
876 new external_single_structure(array(
877 'id' => new external_value(PARAM_INT, 'The user ID'),
878 'fullname' => new external_value(PARAM_NOTAGS, 'The fullname'),
879 'pictureurl' => new external_value(PARAM_URL, 'The picture URL'),
880 ))
881 ),
882 'warnings' => new external_warnings()
883 ));
884 }
f7d9cd23
FM
885
886 /**
887 * Returns the description of the external function parameters.
888 *
889 * @return external_function_parameters
890 * @since Moodle 3.1
891 */
892 public static function get_entries_by_author_parameters() {
893 return new external_function_parameters(array(
894 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
895 'letter' => new external_value(PARAM_ALPHA, 'First letter of firstname or lastname, or either keywords:'
896 . ' \'ALL\' or \'SPECIAL\'.'),
897 'field' => new external_value(PARAM_ALPHA, 'Search and order using: \'FIRSTNAME\' or \'LASTNAME\'', VALUE_DEFAULT,
898 'LASTNAME'),
899 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
900 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
901 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
902 'options' => new external_single_structure(array(
903 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
904 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
905 ), 'An array of options', VALUE_DEFAULT, array())
906 ));
907 }
908
909 /**
910 * Browse a glossary entries by author.
911 *
912 * @param int $id The glossary ID.
913 * @param string $letter A letter, or a special keyword.
914 * @param string $field The field to search from.
915 * @param string $sort The direction of the order.
916 * @param int $from Start returning records from here.
917 * @param int $limit Number of records to return.
918 * @param array $options Array of options.
919 * @return array of warnings and status result
920 * @since Moodle 3.1
921 * @throws moodle_exception
922 */
923 public static function get_entries_by_author($id, $letter, $field = 'LASTNAME', $sort = 'ASC', $from = 0, $limit = 20,
924 $options = array()) {
925 global $DB, $USER;
926
927 $params = self::validate_parameters(self::get_entries_by_author_parameters(), array(
928 'id' => $id,
929 'letter' => $letter,
930 'field' => core_text::strtoupper($field),
931 'sort' => core_text::strtoupper($sort),
932 'from' => $from,
933 'limit' => $limit,
934 'options' => $options,
935 ));
936 $id = $params['id'];
937 $letter = $params['letter'];
938 $field = $params['field'];
939 $sort = $params['sort'];
940 $from = $params['from'];
941 $limit = $params['limit'];
942 $options = $params['options'];
943 $warnings = array();
944
945 if (!in_array($field, array('FIRSTNAME', 'LASTNAME'))) {
946 throw new invalid_parameter_exception('invalidfield');
947 } else if (!in_array($sort, array('ASC', 'DESC'))) {
948 throw new invalid_parameter_exception('invalidsort');
949 }
950
21e30022
FM
951 // Get and validate the glossary.
952 list($glossary, $context) = self::validate_glossary($id);
f7d9cd23
FM
953
954 // Validate the mode.
955 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
956 if (!in_array('author', $modes)) {
957 throw new invalid_parameter_exception('invalidbrowsemode');
958 }
959
f7d9cd23 960 // Fetching the entries.
8382bb4e
FM
961 $entries = array();
962 list($records, $count) = glossary_get_entries_by_author($glossary, $context, $letter, $field, $sort, $from, $limit,
963 $options);
964 foreach ($records as $key => $record) {
965 self::fill_entry_details($record, $context);
966 $entries[] = $record;
f7d9cd23 967 }
8382bb4e 968 $records->close();
f7d9cd23
FM
969
970 return array(
971 'count' => $count,
972 'entries' => $entries,
973 'warnings' => $warnings
974 );
975 }
976
977 /**
978 * Returns the description of the external function return value.
979 *
980 * @return external_description
981 * @since Moodle 3.1
982 */
983 public static function get_entries_by_author_returns() {
984 return new external_single_structure(array(
985 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
986 'entries' => new external_multiple_structure(
987 self::get_entry_return_structure()
988 ),
989 'warnings' => new external_warnings()
990 ));
991 }
e70f58cd
FM
992
993 /**
994 * Returns the description of the external function parameters.
995 *
996 * @return external_function_parameters
997 * @since Moodle 3.1
998 */
999 public static function get_entries_by_author_id_parameters() {
1000 return new external_function_parameters(array(
1001 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1002 'authorid' => new external_value(PARAM_INT, 'The author ID'),
1003 'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1004 'CONCEPT'),
1005 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1006 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1007 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1008 'options' => new external_single_structure(array(
1009 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1010 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1011 ), 'An array of options', VALUE_DEFAULT, array())
1012 ));
1013 }
1014
1015 /**
1016 * Browse a glossary entries by author.
1017 *
1018 * @param int $id The glossary ID.
1019 * @param int $authorid The author ID.
1020 * @param string $order The way to order the results.
1021 * @param string $sort The direction of the order.
1022 * @param int $from Start returning records from here.
1023 * @param int $limit Number of records to return.
1024 * @param array $options Array of options.
1025 * @return array of warnings and status result
1026 * @since Moodle 3.1
1027 * @throws moodle_exception
1028 */
1029 public static function get_entries_by_author_id($id, $authorid, $order = 'CONCEPT', $sort = 'ASC', $from = 0, $limit = 20,
1030 $options = array()) {
1031 global $DB, $USER;
1032
1033 $params = self::validate_parameters(self::get_entries_by_author_id_parameters(), array(
1034 'id' => $id,
1035 'authorid' => $authorid,
1036 'order' => core_text::strtoupper($order),
1037 'sort' => core_text::strtoupper($sort),
1038 'from' => $from,
1039 'limit' => $limit,
1040 'options' => $options,
1041 ));
1042 $id = $params['id'];
1043 $authorid = $params['authorid'];
1044 $order = $params['order'];
1045 $sort = $params['sort'];
1046 $from = $params['from'];
1047 $limit = $params['limit'];
1048 $options = $params['options'];
1049 $warnings = array();
1050
1051 if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1052 throw new invalid_parameter_exception('invalidorder');
1053 } else if (!in_array($sort, array('ASC', 'DESC'))) {
1054 throw new invalid_parameter_exception('invalidsort');
1055 }
1056
21e30022
FM
1057 // Get and validate the glossary.
1058 list($glossary, $context) = self::validate_glossary($id);
e70f58cd
FM
1059
1060 // Validate the mode.
1061 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
1062 if (!in_array('author', $modes)) {
1063 throw new invalid_parameter_exception('invalidbrowsemode');
1064 }
1065
e70f58cd 1066 // Fetching the entries.
8382bb4e
FM
1067 $entries = array();
1068 list($records, $count) = glossary_get_entries_by_author_id($glossary, $context, $authorid, $order, $sort, $from,
1069 $limit, $options);
1070 foreach ($records as $key => $record) {
1071 self::fill_entry_details($record, $context);
1072 $entries[] = $record;
e70f58cd 1073 }
8382bb4e 1074 $records->close();
e70f58cd
FM
1075
1076 return array(
1077 'count' => $count,
1078 'entries' => $entries,
1079 'warnings' => $warnings
1080 );
1081 }
1082
1083 /**
1084 * Returns the description of the external function return value.
1085 *
1086 * @return external_description
1087 * @since Moodle 3.1
1088 */
1089 public static function get_entries_by_author_id_returns() {
1090 return new external_single_structure(array(
1091 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1092 'entries' => new external_multiple_structure(
1093 self::get_entry_return_structure()
1094 ),
1095 'warnings' => new external_warnings()
1096 ));
1097 }
24777f7a
FM
1098
1099 /**
1100 * Returns the description of the external function parameters.
1101 *
1102 * @return external_function_parameters
1103 * @since Moodle 3.1
1104 */
1105 public static function get_entries_by_search_parameters() {
1106 return new external_function_parameters(array(
1107 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1108 'query' => new external_value(PARAM_NOTAGS, 'The query string'),
1109 'fullsearch' => new external_value(PARAM_BOOL, 'The query', VALUE_DEFAULT, 1),
1110 'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1111 'CONCEPT'),
1112 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1113 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1114 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1115 'options' => new external_single_structure(array(
1116 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1117 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1118 ), 'An array of options', VALUE_DEFAULT, array())
1119 ));
1120 }
1121
1122 /**
1123 * Browse a glossary entries using the search.
1124 *
1125 * @param int $id The glossary ID.
1126 * @param string $query The search query.
1127 * @param bool $fullsearch Whether or not full search is required.
1128 * @param string $order The way to order the results.
1129 * @param string $sort The direction of the order.
1130 * @param int $from Start returning records from here.
1131 * @param int $limit Number of records to return.
1132 * @param array $options Array of options.
1133 * @return array of warnings and status result
1134 * @since Moodle 3.1
1135 * @throws moodle_exception
1136 */
1137 public static function get_entries_by_search($id, $query, $fullsearch = true, $order = 'CONCEPT', $sort = 'ASC', $from = 0,
1138 $limit = 20, $options = array()) {
1139 global $DB, $USER;
1140
1141 $params = self::validate_parameters(self::get_entries_by_search_parameters(), array(
1142 'id' => $id,
1143 'query' => $query,
1144 'fullsearch' => $fullsearch,
1145 'order' => core_text::strtoupper($order),
1146 'sort' => core_text::strtoupper($sort),
1147 'from' => $from,
1148 'limit' => $limit,
1149 'options' => $options,
1150 ));
1151 $id = $params['id'];
1152 $query = $params['query'];
1153 $fullsearch = $params['fullsearch'];
1154 $order = $params['order'];
1155 $sort = $params['sort'];
1156 $from = $params['from'];
1157 $limit = $params['limit'];
1158 $options = $params['options'];
1159 $warnings = array();
1160
1161 if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1162 throw new invalid_parameter_exception('invalidorder');
1163 } else if (!in_array($sort, array('ASC', 'DESC'))) {
1164 throw new invalid_parameter_exception('invalidsort');
1165 }
1166
1167 // Get and validate the glossary.
1168 list($glossary, $context) = self::validate_glossary($id);
1169
1170 // Fetching the entries.
1171 $entries = array();
1172 list($records, $count) = glossary_get_entries_by_search($glossary, $context, $query, $fullsearch, $order, $sort, $from,
1173 $limit, $options);
1174 foreach ($records as $key => $record) {
1175 self::fill_entry_details($record, $context);
1176 $entries[] = $record;
1177 }
1178 $records->close();
1179
1180 return array(
1181 'count' => $count,
1182 'entries' => $entries,
1183 'warnings' => $warnings
1184 );
1185 }
1186
1187 /**
1188 * Returns the description of the external function return value.
1189 *
1190 * @return external_description
1191 * @since Moodle 3.1
1192 */
1193 public static function get_entries_by_search_returns() {
1194 return new external_single_structure(array(
1195 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1196 'entries' => new external_multiple_structure(
1197 self::get_entry_return_structure()
1198 ),
1199 'warnings' => new external_warnings()
1200 ));
1201 }
23da998f 1202}