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