MDL-49231 mod_glossary: Minor coding style improvements
[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) = self::validate_glossary($entry->glossaryid);
406         if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) {
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         }
494         $records->close();
496         return array(
497             'count' => $count,
498             'entries' => $entries,
499             'warnings' => $warnings
500         );
501     }
503     /**
504      * Returns the description of the external function return value.
505      *
506      * @return external_description
507      * @since Moodle 3.1
508      */
509     public static function get_entries_by_letter_returns() {
510         return new external_single_structure(array(
511             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
512             'entries' => new external_multiple_structure(
513                 self::get_entry_return_structure()
514             ),
515             'warnings' => new external_warnings()
516         ));
517     }
519     /**
520      * Returns the description of the external function parameters.
521      *
522      * @return external_function_parameters
523      * @since Moodle 3.1
524      */
525     public static function get_entries_by_date_parameters() {
526         return new external_function_parameters(array(
527             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
528             'order' => new external_value(PARAM_ALPHA, 'Order the records by: \'CREATION\' or \'UPDATE\'.',
529                 VALUE_DEFAULT, 'UPDATE'),
530             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'DESC'),
531             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
532             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
533             'options' => new external_single_structure(array(
534                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
535                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
536             ), 'An array of options', VALUE_DEFAULT, array())
537         ));
538     }
540     /**
541      * Browse a glossary entries by date.
542      *
543      * @param int $id The glossary ID.
544      * @param string $order The way to order the records.
545      * @param string $sort The direction of the order.
546      * @param int $from Start returning records from here.
547      * @param int $limit Number of records to return.
548      * @param array $options Array of options.
549      * @return array Containing count, entries and warnings.
550      * @since Moodle 3.1
551      * @throws moodle_exception
552      * @throws invalid_parameter_exception
553      */
554     public static function get_entries_by_date($id, $order, $sort, $from, $limit, $options) {
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();
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         }
577         // Get and validate the glossary.
578         list($glossary, $context) = self::validate_glossary($id);
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         }
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;
591         }
592         $records->close();
594         return array(
595             'count' => $count,
596             'entries' => $entries,
597             'warnings' => $warnings
598         );
599     }
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     }
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, 'The glossary 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     }
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 Containing count, categories and warnings.
638      * @since Moodle 3.1
639      * @throws moodle_exception
640      */
641     public static function get_categories($id, $from, $limit) {
642         $params = self::validate_parameters(self::get_categories_parameters(), array(
643             'id' => $id,
644             'from' => $from,
645             'limit' => $limit
646         ));
647         $id = $params['id'];
648         $from = $params['from'];
649         $limit = $params['limit'];
650         $warnings = array();
652         // Get and validate the glossary.
653         list($glossary, $context) = self::validate_glossary($id);
655         // Fetch the categories.
656         $categories = array();
657         list($records, $count) = glossary_get_categories($glossary, $from, $limit);
658         foreach ($records as $category) {
659             $category->name = external_format_string($category->name, $context->id);
660             $categories[] = $category;
661         }
663         return array(
664             'count' => $count,
665             'categories' => $categories,
666             'warnings' => array(),
667         );
668     }
670     /**
671      * Returns the description of the external function return value.
672      *
673      * @return external_description
674      * @since Moodle 3.1
675      */
676     public static function get_categories_returns() {
677         return new external_single_structure(array(
678             'count' => new external_value(PARAM_INT, 'The total number of records.'),
679             'categories' => new external_multiple_structure(
680                 new external_single_structure(array(
681                     'id' => new external_value(PARAM_INT, 'The category ID'),
682                     'glossaryid' => new external_value(PARAM_INT, 'The glossary ID'),
683                     'name' => new external_value(PARAM_RAW, 'The name of the category'),
684                     'usedynalink' => new external_value(PARAM_BOOL, 'Whether the category is automatically linked'),
685                 ))
686             ),
687             'warnings' => new external_warnings()
688         ));
689     }
691     /**
692      * Returns the description of the external function parameters.
693      *
694      * @return external_function_parameters
695      * @since Moodle 3.1
696      */
697     public static function get_entries_by_category_parameters() {
698         return new external_function_parameters(array(
699             'id' => new external_value(PARAM_INT, 'The glossary ID.'),
700             'categoryid' => new external_value(PARAM_INT, 'The category ID. Use \'' . GLOSSARY_SHOW_ALL_CATEGORIES . '\' for all' .
701                 ' categories, or \'' . GLOSSARY_SHOW_NOT_CATEGORISED . '\' for uncategorised entries.'),
702             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
703             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
704             'options' => new external_single_structure(array(
705                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
706                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
707             ), 'An array of options', VALUE_DEFAULT, array())
708         ));
709     }
711     /**
712      * Browse a glossary entries by category.
713      *
714      * @param int $id The glossary ID.
715      * @param int $categoryid The category ID.
716      * @param int $from Start returning records from here.
717      * @param int $limit Number of records to return.
718      * @param array $options Array of options.
719      * @return array Containing count, entries and warnings.
720      * @since Moodle 3.1
721      * @throws moodle_exception
722      * @throws invalid_parameter_exception
723      */
724     public static function get_entries_by_category($id, $categoryid, $from, $limit, $options) {
725         global $DB;
727         $params = self::validate_parameters(self::get_entries_by_category_parameters(), array(
728             'id' => $id,
729             'categoryid' => $categoryid,
730             'from' => $from,
731             'limit' => $limit,
732             'options' => $options,
733         ));
734         $id = $params['id'];
735         $categoryid = $params['categoryid'];
736         $from = $params['from'];
737         $limit = $params['limit'];
738         $options = $params['options'];
739         $warnings = array();
741         // Get and validate the glossary.
742         list($glossary, $context) = self::validate_glossary($id);
744         // Validate the mode.
745         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
746         if (!in_array('cat', $modes)) {
747             throw new invalid_parameter_exception('invalidbrowsemode');
748         }
750         // Validate the category.
751         if (in_array($categoryid, array(GLOSSARY_SHOW_ALL_CATEGORIES, GLOSSARY_SHOW_NOT_CATEGORISED))) {
752             // All good.
753         } else if (!$DB->record_exists('glossary_categories', array('id' => $categoryid, 'glossaryid' => $id))) {
754             throw new invalid_parameter_exception('invalidcategory');
755         }
757         // Fetching the entries.
758         $entries = array();
759         list($records, $count) = glossary_get_entries_by_category($glossary, $context, $categoryid, $from, $limit, $options);
760         foreach ($records as $key => $record) {
761             self::fill_entry_details($record, $context);
762             if ($record->categoryid === null) {
763                 $record->categoryid = GLOSSARY_SHOW_NOT_CATEGORISED;
764             }
765             if (isset($record->categoryname)) {
766                 $record->categoryname = external_format_string($record->categoryname, $context->id);
767             }
768             $entries[] = $record;
769         }
770         $records->close();
772         return array(
773             'count' => $count,
774             'entries' => $entries,
775             'warnings' => $warnings
776         );
777     }
779     /**
780      * Returns the description of the external function return value.
781      *
782      * @return external_description
783      * @since Moodle 3.1
784      */
785     public static function get_entries_by_category_returns() {
786         return new external_single_structure(array(
787             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
788             'entries' => new external_multiple_structure(
789                 self::get_entry_return_structure(true)
790             ),
791             'warnings' => new external_warnings()
792         ));
793     }
795     /**
796      * Returns the description of the external function parameters.
797      *
798      * @return external_function_parameters
799      * @since Moodle 3.1
800      */
801     public static function get_authors_parameters() {
802         return new external_function_parameters(array(
803             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
804             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
805             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
806             'options' => new external_single_structure(array(
807                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes self even if all of their entries' .
808                     ' require approval. When true, also includes authors only having entries pending approval.', VALUE_DEFAULT, 0)
809             ), 'An array of options', VALUE_DEFAULT, array())
810         ));
811     }
813     /**
814      * Get the authors of a glossary.
815      *
816      * @param int $id The glossary ID.
817      * @param int $from Start returning records from here.
818      * @param int $limit Number of records to return.
819      * @param array $options Array of options.
820      * @return array Containing count, authors and warnings.
821      * @since Moodle 3.1
822      * @throws moodle_exception
823      */
824     public static function get_authors($id, $from, $limit, $options) {
825         global $PAGE;
827         $params = self::validate_parameters(self::get_authors_parameters(), array(
828             'id' => $id,
829             'from' => $from,
830             'limit' => $limit,
831             'options' => $options,
832         ));
833         $id = $params['id'];
834         $from = $params['from'];
835         $limit = $params['limit'];
836         $options = $params['options'];
837         $warnings = array();
839         // Get and validate the glossary.
840         list($glossary, $context) = self::validate_glossary($id);
842         // Fetching the entries.
843         list($users, $count) = glossary_get_authors($glossary, $context, $limit, $from, $options);
845         $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
846         foreach ($users as $user) {
847             $userpicture = new user_picture($user);
848             $userpicture->size = 1;
850             $author = new stdClass();
851             $author->id = $user->id;
852             $author->fullname = fullname($user, $canviewfullnames);
853             $author->pictureurl = $userpicture->get_url($PAGE)->out(false);
854             $authors[] = $author;
855         }
856         $users->close();
858         return array(
859             'count' => $count,
860             'authors' => $authors,
861             'warnings' => array(),
862         );
863     }
865     /**
866      * Returns the description of the external function return value.
867      *
868      * @return external_description
869      * @since Moodle 3.1
870      */
871     public static function get_authors_returns() {
872         return new external_single_structure(array(
873             'count' => new external_value(PARAM_INT, 'The total number of records.'),
874             'authors' => new external_multiple_structure(
875                 new external_single_structure(array(
876                     'id' => new external_value(PARAM_INT, 'The user ID'),
877                     'fullname' => new external_value(PARAM_NOTAGS, 'The fullname'),
878                     'pictureurl' => new external_value(PARAM_URL, 'The picture URL'),
879                 ))
880             ),
881             'warnings' => new external_warnings()
882         ));
883     }
885     /**
886      * Returns the description of the external function parameters.
887      *
888      * @return external_function_parameters
889      * @since Moodle 3.1
890      */
891     public static function get_entries_by_author_parameters() {
892         return new external_function_parameters(array(
893             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
894             'letter' => new external_value(PARAM_ALPHA, 'First letter of firstname or lastname, or either keywords:'
895                 . ' \'ALL\' or \'SPECIAL\'.'),
896             'field' => new external_value(PARAM_ALPHA, 'Search and order using: \'FIRSTNAME\' or \'LASTNAME\'', VALUE_DEFAULT,
897                 'LASTNAME'),
898             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
899             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
900             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
901             'options' => new external_single_structure(array(
902                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
903                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
904             ), 'An array of options', VALUE_DEFAULT, array())
905         ));
906     }
908     /**
909      * Browse a glossary entries by author.
910      *
911      * @param int $id The glossary ID.
912      * @param string $letter A letter, or a special keyword.
913      * @param string $field The field to search from.
914      * @param string $sort The direction of the order.
915      * @param int $from Start returning records from here.
916      * @param int $limit Number of records to return.
917      * @param array $options Array of options.
918      * @return array Containing count, entries and warnings.
919      * @since Moodle 3.1
920      * @throws moodle_exception
921      * @throws invalid_parameter_exception
922      */
923     public static function get_entries_by_author($id, $letter, $field, $sort, $from, $limit, $options) {
924         $params = self::validate_parameters(self::get_entries_by_author_parameters(), array(
925             'id' => $id,
926             'letter' => $letter,
927             'field' => core_text::strtoupper($field),
928             'sort' => core_text::strtoupper($sort),
929             'from' => $from,
930             'limit' => $limit,
931             'options' => $options,
932         ));
933         $id = $params['id'];
934         $letter = $params['letter'];
935         $field = $params['field'];
936         $sort = $params['sort'];
937         $from = $params['from'];
938         $limit = $params['limit'];
939         $options = $params['options'];
940         $warnings = array();
942         if (!in_array($field, array('FIRSTNAME', 'LASTNAME'))) {
943             throw new invalid_parameter_exception('invalidfield');
944         } else if (!in_array($sort, array('ASC', 'DESC'))) {
945             throw new invalid_parameter_exception('invalidsort');
946         }
948         // Get and validate the glossary.
949         list($glossary, $context) = self::validate_glossary($id);
951         // Validate the mode.
952         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
953         if (!in_array('author', $modes)) {
954             throw new invalid_parameter_exception('invalidbrowsemode');
955         }
957         // Fetching the entries.
958         $entries = array();
959         list($records, $count) = glossary_get_entries_by_author($glossary, $context, $letter, $field, $sort, $from, $limit,
960             $options);
961         foreach ($records as $key => $record) {
962             self::fill_entry_details($record, $context);
963             $entries[] = $record;
964         }
965         $records->close();
967         return array(
968             'count' => $count,
969             'entries' => $entries,
970             'warnings' => $warnings
971         );
972     }
974     /**
975      * Returns the description of the external function return value.
976      *
977      * @return external_description
978      * @since Moodle 3.1
979      */
980     public static function get_entries_by_author_returns() {
981         return new external_single_structure(array(
982             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
983             'entries' => new external_multiple_structure(
984                 self::get_entry_return_structure()
985             ),
986             'warnings' => new external_warnings()
987         ));
988     }
990     /**
991      * Returns the description of the external function parameters.
992      *
993      * @return external_function_parameters
994      * @since Moodle 3.1
995      */
996     public static function get_entries_by_author_id_parameters() {
997         return new external_function_parameters(array(
998             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
999             'authorid' => new external_value(PARAM_INT, 'The author ID'),
1000             'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1001                 'CONCEPT'),
1002             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1003             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1004             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1005             'options' => new external_single_structure(array(
1006                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1007                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1008             ), 'An array of options', VALUE_DEFAULT, array())
1009         ));
1010     }
1012     /**
1013      * Browse a glossary entries by author.
1014      *
1015      * @param int $id The glossary ID.
1016      * @param int $authorid The author ID.
1017      * @param string $order The way to order the results.
1018      * @param string $sort The direction of the order.
1019      * @param int $from Start returning records from here.
1020      * @param int $limit Number of records to return.
1021      * @param array $options Array of options.
1022      * @return array Containing count, entries and warnings.
1023      * @since Moodle 3.1
1024      * @throws moodle_exception
1025      * @throws invalid_parameter_exception
1026      */
1027     public static function get_entries_by_author_id($id, $authorid, $order, $sort, $from, $limit, $options) {
1028         $params = self::validate_parameters(self::get_entries_by_author_id_parameters(), array(
1029             'id' => $id,
1030             'authorid' => $authorid,
1031             'order' => core_text::strtoupper($order),
1032             'sort' => core_text::strtoupper($sort),
1033             'from' => $from,
1034             'limit' => $limit,
1035             'options' => $options,
1036         ));
1037         $id = $params['id'];
1038         $authorid = $params['authorid'];
1039         $order = $params['order'];
1040         $sort = $params['sort'];
1041         $from = $params['from'];
1042         $limit = $params['limit'];
1043         $options = $params['options'];
1044         $warnings = array();
1046         if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1047             throw new invalid_parameter_exception('invalidorder');
1048         } else if (!in_array($sort, array('ASC', 'DESC'))) {
1049             throw new invalid_parameter_exception('invalidsort');
1050         }
1052         // Get and validate the glossary.
1053         list($glossary, $context) = self::validate_glossary($id);
1055         // Validate the mode.
1056         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
1057         if (!in_array('author', $modes)) {
1058             throw new invalid_parameter_exception('invalidbrowsemode');
1059         }
1061         // Fetching the entries.
1062         $entries = array();
1063         list($records, $count) = glossary_get_entries_by_author_id($glossary, $context, $authorid, $order, $sort, $from,
1064             $limit, $options);
1065         foreach ($records as $key => $record) {
1066             self::fill_entry_details($record, $context);
1067             $entries[] = $record;
1068         }
1069         $records->close();
1071         return array(
1072             'count' => $count,
1073             'entries' => $entries,
1074             'warnings' => $warnings
1075         );
1076     }
1078     /**
1079      * Returns the description of the external function return value.
1080      *
1081      * @return external_description
1082      * @since Moodle 3.1
1083      */
1084     public static function get_entries_by_author_id_returns() {
1085         return new external_single_structure(array(
1086             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1087             'entries' => new external_multiple_structure(
1088                 self::get_entry_return_structure()
1089             ),
1090             'warnings' => new external_warnings()
1091         ));
1092     }
1094     /**
1095      * Returns the description of the external function parameters.
1096      *
1097      * @return external_function_parameters
1098      * @since Moodle 3.1
1099      */
1100     public static function get_entries_by_search_parameters() {
1101         return new external_function_parameters(array(
1102             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1103             'query' => new external_value(PARAM_NOTAGS, 'The query string'),
1104             'fullsearch' => new external_value(PARAM_BOOL, 'The query', VALUE_DEFAULT, 1),
1105             'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1106                 'CONCEPT'),
1107             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1108             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1109             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1110             'options' => new external_single_structure(array(
1111                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1112                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1113             ), 'An array of options', VALUE_DEFAULT, array())
1114         ));
1115     }
1117     /**
1118      * Browse a glossary entries using the search.
1119      *
1120      * @param int $id The glossary ID.
1121      * @param string $query The search query.
1122      * @param bool $fullsearch Whether or not full search is required.
1123      * @param string $order The way to order the results.
1124      * @param string $sort The direction of the order.
1125      * @param int $from Start returning records from here.
1126      * @param int $limit Number of records to return.
1127      * @param array $options Array of options.
1128      * @return array Containing count, entries and warnings.
1129      * @since Moodle 3.1
1130      * @throws moodle_exception
1131      * @throws invalid_parameter_exception
1132      */
1133     public static function get_entries_by_search($id, $query, $fullsearch, $order, $sort, $from, $limit, $options) {
1134         $params = self::validate_parameters(self::get_entries_by_search_parameters(), array(
1135             'id' => $id,
1136             'query' => $query,
1137             'fullsearch' => $fullsearch,
1138             'order' => core_text::strtoupper($order),
1139             'sort' => core_text::strtoupper($sort),
1140             'from' => $from,
1141             'limit' => $limit,
1142             'options' => $options,
1143         ));
1144         $id = $params['id'];
1145         $query = $params['query'];
1146         $fullsearch = $params['fullsearch'];
1147         $order = $params['order'];
1148         $sort = $params['sort'];
1149         $from = $params['from'];
1150         $limit = $params['limit'];
1151         $options = $params['options'];
1152         $warnings = array();
1154         if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1155             throw new invalid_parameter_exception('invalidorder');
1156         } else if (!in_array($sort, array('ASC', 'DESC'))) {
1157             throw new invalid_parameter_exception('invalidsort');
1158         }
1160         // Get and validate the glossary.
1161         list($glossary, $context) = self::validate_glossary($id);
1163         // Fetching the entries.
1164         $entries = array();
1165         list($records, $count) = glossary_get_entries_by_search($glossary, $context, $query, $fullsearch, $order, $sort, $from,
1166             $limit, $options);
1167         foreach ($records as $key => $record) {
1168             self::fill_entry_details($record, $context);
1169             $entries[] = $record;
1170         }
1171         $records->close();
1173         return array(
1174             'count' => $count,
1175             'entries' => $entries,
1176             'warnings' => $warnings
1177         );
1178     }
1180     /**
1181      * Returns the description of the external function return value.
1182      *
1183      * @return external_description
1184      * @since Moodle 3.1
1185      */
1186     public static function get_entries_by_search_returns() {
1187         return new external_single_structure(array(
1188             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1189             'entries' => new external_multiple_structure(
1190                 self::get_entry_return_structure()
1191             ),
1192             'warnings' => new external_warnings()
1193         ));
1194     }
1196     /**
1197      * Returns the description of the external function parameters.
1198      *
1199      * @return external_function_parameters
1200      * @since Moodle 3.1
1201      */
1202     public static function get_entries_by_term_parameters() {
1203         return new external_function_parameters(array(
1204             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1205             'term' => new external_value(PARAM_NOTAGS, 'The entry concept, or alias'),
1206             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1207             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1208             'options' => new external_single_structure(array(
1209                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1210                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1211             ), 'An array of options', VALUE_DEFAULT, array())
1212         ));
1213     }
1215     /**
1216      * Browse a glossary entries using a term matching the concept or alias.
1217      *
1218      * @param int $id The glossary ID.
1219      * @param string $term The term.
1220      * @param int $from Start returning records from here.
1221      * @param int $limit Number of records to return.
1222      * @param array $options Array of options.
1223      * @return array Containing count, entries and warnings.
1224      * @since Moodle 3.1
1225      * @throws moodle_exception
1226      */
1227     public static function get_entries_by_term($id, $term, $from, $limit, $options) {
1228         $params = self::validate_parameters(self::get_entries_by_term_parameters(), array(
1229             'id' => $id,
1230             'term' => $term,
1231             'from' => $from,
1232             'limit' => $limit,
1233             'options' => $options,
1234         ));
1235         $id = $params['id'];
1236         $term = $params['term'];
1237         $from = $params['from'];
1238         $limit = $params['limit'];
1239         $options = $params['options'];
1240         $warnings = array();
1242         // Get and validate the glossary.
1243         list($glossary, $context) = self::validate_glossary($id);
1245         // Fetching the entries.
1246         $entries = array();
1247         list($records, $count) = glossary_get_entries_by_term($glossary, $context, $term, $from, $limit, $options);
1248         foreach ($records as $key => $record) {
1249             self::fill_entry_details($record, $context);
1250             $entries[] = $record;
1251         }
1252         $records->close();
1254         return array(
1255             'count' => $count,
1256             'entries' => $entries,
1257             'warnings' => $warnings
1258         );
1259     }
1261     /**
1262      * Returns the description of the external function return value.
1263      *
1264      * @return external_description
1265      * @since Moodle 3.1
1266      */
1267     public static function get_entries_by_term_returns() {
1268         return new external_single_structure(array(
1269             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1270             'entries' => new external_multiple_structure(
1271                 self::get_entry_return_structure()
1272             ),
1273             'warnings' => new external_warnings()
1274         ));
1275     }
1277     /**
1278      * Returns the description of the external function parameters.
1279      *
1280      * @return external_function_parameters
1281      * @since Moodle 3.1
1282      */
1283     public static function get_entries_to_approve_parameters() {
1284         return new external_function_parameters(array(
1285             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1286             'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
1287             'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1288                 'CONCEPT'),
1289             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1290             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1291             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1292             'options' => new external_single_structure(array(), 'An array of options', VALUE_DEFAULT, array())
1293         ));
1294     }
1296     /**
1297      * Browse a glossary entries using a term matching the concept or alias.
1298      *
1299      * @param int $id The glossary ID.
1300      * @param string $letter A letter, or a special keyword.
1301      * @param string $order The way to order the records.
1302      * @param string $sort The direction of the order.
1303      * @param int $from Start returning records from here.
1304      * @param int $limit Number of records to return.
1305      * @return array Containing count, entries and warnings.
1306      * @since Moodle 3.1
1307      * @throws moodle_exception
1308      */
1309     public static function get_entries_to_approve($id, $letter, $order, $sort, $from, $limit) {
1310         $params = self::validate_parameters(self::get_entries_to_approve_parameters(), array(
1311             'id' => $id,
1312             'letter' => $letter,
1313             'order' => $order,
1314             'sort' => $sort,
1315             'from' => $from,
1316             'limit' => $limit
1317         ));
1318         $id = $params['id'];
1319         $letter = $params['letter'];
1320         $order = $params['order'];
1321         $sort = $params['sort'];
1322         $from = $params['from'];
1323         $limit = $params['limit'];
1324         $warnings = array();
1326         // Get and validate the glossary.
1327         list($glossary, $context) = self::validate_glossary($id);
1329         // Check the permissions.
1330         require_capability('mod/glossary:approve', $context);
1332         // Fetching the entries.
1333         $entries = array();
1334         list($records, $count) = glossary_get_entries_to_approve($glossary, $context, $letter, $order, $sort, $from, $limit);
1335         foreach ($records as $key => $record) {
1336             self::fill_entry_details($record, $context);
1337             $entries[] = $record;
1338         }
1339         $records->close();
1341         return array(
1342             'count' => $count,
1343             'entries' => $entries,
1344             'warnings' => $warnings
1345         );
1346     }
1348     /**
1349      * Returns the description of the external function return value.
1350      *
1351      * @return external_description
1352      * @since Moodle 3.1
1353      */
1354     public static function get_entries_to_approve_returns() {
1355         return new external_single_structure(array(
1356             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1357             'entries' => new external_multiple_structure(
1358                 self::get_entry_return_structure()
1359             ),
1360             'warnings' => new external_warnings()
1361         ));
1362     }
1364     /**
1365      * Returns the description of the external function parameters.
1366      *
1367      * @return external_function_parameters
1368      * @since Moodle 3.1
1369      */
1370     public static function get_entry_by_id_parameters() {
1371         return new external_function_parameters(array(
1372             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1373         ));
1374     }
1376     /**
1377      * Get an entry.
1378      *
1379      * @param int $id The entry ID.
1380      * @return array Containing entry and warnings.
1381      * @since Moodle 3.1
1382      * @throws moodle_exception
1383      * @throws invalid_parameter_exception
1384      */
1385     public static function get_entry_by_id($id) {
1386         global $DB, $USER;
1388         $params = self::validate_parameters(self::get_entry_by_id_parameters(), array('id' => $id));
1389         $id = $params['id'];
1390         $warnings = array();
1392         // Get and validate the glossary.
1393         $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST);
1394         list($glossary, $context) = self::validate_glossary($entry->glossaryid);
1396         if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) {
1397             throw new invalid_parameter_exception('invalidentry');
1398         }
1400         $entry = glossary_get_entry_by_id($id);
1401         self::fill_entry_details($entry, $context);
1403         return array(
1404             'entry' => $entry,
1405             'warnings' => $warnings
1406         );
1407     }
1409     /**
1410      * Returns the description of the external function return value.
1411      *
1412      * @return external_description
1413      * @since Moodle 3.1
1414      */
1415     public static function get_entry_by_id_returns() {
1416         return new external_single_structure(array(
1417             'entry' => self::get_entry_return_structure(),
1418             'warnings' => new external_warnings()
1419         ));
1420     }