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