MDL-64656 core_tag: Return tags in modules and blog
[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             'definitioninlinefiles' => new external_files('entry definition inline files', VALUE_OPTIONAL),
94             'attachment' => new external_value(PARAM_BOOL, 'Whether or not the entry has attachments'),
95             'attachments' => new external_files('attachments', VALUE_OPTIONAL),
96             'timecreated' => new external_value(PARAM_INT, 'Time created'),
97             'timemodified' => new external_value(PARAM_INT, 'Time modified'),
98             'teacherentry' => new external_value(PARAM_BOOL, 'The entry was created by a teacher, or equivalent.'),
99             'sourceglossaryid' => new external_value(PARAM_INT, 'The source glossary ID'),
100             'usedynalink' => new external_value(PARAM_BOOL, 'Whether the concept should be automatically linked'),
101             'casesensitive' => new external_value(PARAM_BOOL, 'When true, the matching is case sensitive'),
102             'fullmatch' => new external_value(PARAM_BOOL, 'When true, the matching is done on full words only'),
103             'approved' => new external_value(PARAM_BOOL, 'Whether the entry was approved'),
104             'tags' => new external_multiple_structure(
105                 \core_tag\external\tag_item_exporter::get_read_structure(), 'Tags', VALUE_OPTIONAL
106             ),
107         );
109         if ($includecat) {
110             $params['categoryid'] = new external_value(PARAM_INT, 'The category ID. This may be' .
111                 ' \''. GLOSSARY_SHOW_NOT_CATEGORISED . '\' when the entry is not categorised', VALUE_DEFAULT,
112                 GLOSSARY_SHOW_NOT_CATEGORISED);
113             $params['categoryname'] = new external_value(PARAM_RAW, 'The category name. May be empty when the entry is' .
114                 ' not categorised, or the request was limited to one category.', VALUE_DEFAULT, '');
115         }
117         return new external_single_structure($params);
118     }
120     /**
121      * Fill in an entry object.
122      *
123      * This adds additional required fields for the external function to return.
124      *
125      * @param  stdClass $entry   The entry.
126      * @param  context  $context The context the entry belongs to.
127      * @return void
128      */
129     protected static function fill_entry_details($entry, $context) {
130         global $PAGE;
131         $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
133         // Format concept and definition.
134         $entry->concept = external_format_string($entry->concept, $context->id);
135         list($entry->definition, $entry->definitionformat) = external_format_text($entry->definition, $entry->definitionformat,
136             $context->id, 'mod_glossary', 'entry', $entry->id);
138         // Author details.
139         $user = mod_glossary_entry_query_builder::get_user_from_record($entry);
140         $userpicture = new user_picture($user);
141         $userpicture->size = 1;
142         $entry->userfullname = fullname($user, $canviewfullnames);
143         $entry->userpictureurl = $userpicture->get_url($PAGE)->out(false);
145         // Fetch attachments.
146         $entry->attachment = !empty($entry->attachment) ? 1 : 0;
147         $entry->attachments = array();
148         if ($entry->attachment) {
149             $entry->attachments = external_util::get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id);
150         }
151         $definitioninlinefiles = external_util::get_area_files($context->id, 'mod_glossary', 'entry', $entry->id);
152         if (!empty($definitioninlinefiles)) {
153             $entry->definitioninlinefiles = $definitioninlinefiles;
154         }
156         $entry->tags = \core_tag\external\util::get_item_tags('mod_glossary', 'glossary_entries', $entry->id);
157     }
159     /**
160      * Validate a glossary via ID.
161      *
162      * @param  int $id The glossary ID.
163      * @return array Contains glossary, context, course and cm.
164      */
165     protected static function validate_glossary($id) {
166         global $DB;
167         $glossary = $DB->get_record('glossary', array('id' => $id), '*', MUST_EXIST);
168         list($course, $cm) = get_course_and_cm_from_instance($glossary, 'glossary');
169         $context = context_module::instance($cm->id);
170         self::validate_context($context);
171         return array($glossary, $context, $course, $cm);
172     }
174     /**
175      * Describes the parameters for get_glossaries_by_courses.
176      *
177      * @return external_function_parameters
178      * @since Moodle 3.1
179      */
180     public static function get_glossaries_by_courses_parameters() {
181         return new external_function_parameters (
182             array(
183                 'courseids' => new external_multiple_structure(
184                     new external_value(PARAM_INT, 'course id'),
185                     'Array of course IDs', VALUE_DEFAULT, array()
186                 ),
187             )
188         );
189     }
191     /**
192      * Returns a list of glossaries in a provided list of courses.
193      *
194      * If no list is provided all glossaries that the user can view will be returned.
195      *
196      * @param array $courseids the course IDs.
197      * @return array of glossaries
198      * @since Moodle 3.1
199      */
200     public static function get_glossaries_by_courses($courseids = array()) {
201         $params = self::validate_parameters(self::get_glossaries_by_courses_parameters(), array('courseids' => $courseids));
203         $warnings = array();
204         $courses = array();
205         $courseids = $params['courseids'];
207         if (empty($courseids)) {
208             $courses = enrol_get_my_courses();
209             $courseids = array_keys($courses);
210         }
212         // Array to store the glossaries to return.
213         $glossaries = array();
214         $modes = array();
216         // Ensure there are courseids to loop through.
217         if (!empty($courseids)) {
218             list($courses, $warnings) = external_util::validate_courses($courseids, $courses);
220             // Get the glossaries in these courses, this function checks users visibility permissions.
221             $glossaries = get_all_instances_in_courses('glossary', $courses);
222             foreach ($glossaries as $glossary) {
223                 $context = context_module::instance($glossary->coursemodule);
224                 $glossary->name = external_format_string($glossary->name, $context->id);
225                 list($glossary->intro, $glossary->introformat) = external_format_text($glossary->intro, $glossary->introformat,
226                     $context->id, 'mod_glossary', 'intro', null);
227                 $glossary->introfiles = external_util::get_area_files($context->id, 'mod_glossary', 'intro', false, false);
229                 // Make sure we have a number of entries per page.
230                 if (!$glossary->entbypage) {
231                     $glossary->entbypage = $CFG->glossary_entbypage;
232                 }
234                 // Add the list of browsing modes.
235                 if (!isset($modes[$glossary->displayformat])) {
236                     $modes[$glossary->displayformat] = self::get_browse_modes_from_display_format($glossary->displayformat);
237                 }
238                 $glossary->browsemodes = $modes[$glossary->displayformat];
239                 $glossary->canaddentry = has_capability('mod/glossary:write', $context) ? 1 : 0;
240             }
241         }
243         $result = array();
244         $result['glossaries'] = $glossaries;
245         $result['warnings'] = $warnings;
246         return $result;
247     }
249     /**
250      * Describes the get_glossaries_by_courses return value.
251      *
252      * @return external_single_structure
253      * @since Moodle 3.1
254      */
255     public static function get_glossaries_by_courses_returns() {
256         return new external_single_structure(array(
257             'glossaries' => new external_multiple_structure(
258                 new external_single_structure(array(
259                     'id' => new external_value(PARAM_INT, 'Glossary id'),
260                     'coursemodule' => new external_value(PARAM_INT, 'Course module id'),
261                     'course' => new external_value(PARAM_INT, 'Course id'),
262                     'name' => new external_value(PARAM_RAW, 'Glossary name'),
263                     'intro' => new external_value(PARAM_RAW, 'The Glossary intro'),
264                     'introformat' => new external_format_value('intro'),
265                     'introfiles' => new external_files('Files in the introduction text', VALUE_OPTIONAL),
266                     'allowduplicatedentries' => new external_value(PARAM_INT, 'If enabled, multiple entries can have the' .
267                         ' same concept name'),
268                     'displayformat' => new external_value(PARAM_TEXT, 'Display format type'),
269                     'mainglossary' => new external_value(PARAM_INT, 'If enabled this glossary is a main glossary.'),
270                     'showspecial' => new external_value(PARAM_INT, 'If enabled, participants can browse the glossary by' .
271                         ' special characters, such as @ and #'),
272                     'showalphabet' => new external_value(PARAM_INT, 'If enabled, participants can browse the glossary by' .
273                         ' letters of the alphabet'),
274                     'showall' => new external_value(PARAM_INT, 'If enabled, participants can browse all entries at once'),
275                     'allowcomments' => new external_value(PARAM_INT, 'If enabled, all participants with permission to' .
276                         ' create comments will be able to add comments to glossary entries'),
277                     'allowprintview' => new external_value(PARAM_INT, 'If enabled, students are provided with a link to a' .
278                         ' printer-friendly version of the glossary. The link is always available to teachers'),
279                     'usedynalink' => new external_value(PARAM_INT, 'If site-wide glossary auto-linking has been enabled' .
280                         ' by an administrator and this checkbox is ticked, the entry will be automatically linked' .
281                         ' wherever the concept words and phrases appear throughout the rest of the course.'),
282                     'defaultapproval' => new external_value(PARAM_INT, 'If set to no, entries require approving by a' .
283                         ' teacher before they are viewable by everyone.'),
284                     'approvaldisplayformat' => new external_value(PARAM_TEXT, 'When approving glossary items you may wish' .
285                         ' to use a different display format'),
286                     'globalglossary' => new external_value(PARAM_INT, ''),
287                     'entbypage' => new external_value(PARAM_INT, 'Entries shown per page'),
288                     'editalways' => new external_value(PARAM_INT, 'Always allow editing'),
289                     'rsstype' => new external_value(PARAM_INT, 'To enable the RSS feed for this activity, select either' .
290                         ' concepts with author or concepts without author to be included in the feed'),
291                     'rssarticles' => new external_value(PARAM_INT, 'This setting specifies the number of glossary entry' .
292                         ' concepts to include in the RSS feed. Between 5 and 20 generally acceptable'),
293                     'assessed' => new external_value(PARAM_INT, 'Aggregate type'),
294                     'assesstimestart' => new external_value(PARAM_INT, 'Restrict rating to items created after this'),
295                     'assesstimefinish' => new external_value(PARAM_INT, 'Restrict rating to items created before this'),
296                     'scale' => new external_value(PARAM_INT, 'Scale ID'),
297                     'timecreated' => new external_value(PARAM_INT, 'Time created'),
298                     'timemodified' => new external_value(PARAM_INT, 'Time modified'),
299                     'completionentries' => new external_value(PARAM_INT, 'Number of entries to complete'),
300                     'section' => new external_value(PARAM_INT, 'Section'),
301                     'visible' => new external_value(PARAM_INT, 'Visible'),
302                     'groupmode' => new external_value(PARAM_INT, 'Group mode'),
303                     'groupingid' => new external_value(PARAM_INT, 'Grouping ID'),
304                     'browsemodes' => new external_multiple_structure(
305                         new external_value(PARAM_ALPHA, 'Modes of browsing allowed')
306                     ),
307                     'canaddentry' => new external_value(PARAM_INT, 'Whether the user can add a new entry', VALUE_OPTIONAL),
308                 ), 'Glossaries')
309             ),
310             'warnings' => new external_warnings())
311         );
312     }
314     /**
315      * Returns the description of the external function parameters.
316      *
317      * @return external_function_parameters
318      * @since Moodle 3.1
319      */
320     public static function view_glossary_parameters() {
321         return new external_function_parameters(array(
322             'id' => new external_value(PARAM_INT, 'Glossary instance ID'),
323             'mode' => new external_value(PARAM_ALPHA, 'The mode in which the glossary is viewed'),
324         ));
325     }
327     /**
328      * Notify that the course module was viewed.
329      *
330      * @param int $id The glossary instance ID.
331      * @param string $mode The view mode.
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         $params = self::validate_parameters(self::view_glossary_parameters(), array(
338             'id' => $id,
339             'mode' => $mode
340         ));
341         $id = $params['id'];
342         $mode = $params['mode'];
343         $warnings = array();
345         // Get and validate the glossary.
346         list($glossary, $context, $course, $cm) = self::validate_glossary($id);
348         // Trigger module viewed event.
349         glossary_view($glossary, $course, $cm, $context, $mode);
351         return array(
352             'status' => true,
353             'warnings' => $warnings
354         );
355     }
357     /**
358      * Returns the description of the external function return value.
359      *
360      * @return external_description
361      * @since Moodle 3.1
362      */
363     public static function view_glossary_returns() {
364         return new external_single_structure(array(
365             'status' => new external_value(PARAM_BOOL, 'True on success'),
366             'warnings' => new external_warnings()
367         ));
368     }
370     /**
371      * Returns the description of the external function parameters.
372      *
373      * @return external_function_parameters
374      * @since Moodle 3.1
375      */
376     public static function view_entry_parameters() {
377         return new external_function_parameters(array(
378             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
379         ));
380     }
382     /**
383      * Notify that the entry was viewed.
384      *
385      * @param int $id The entry ID.
386      * @return array of warnings and status result
387      * @since Moodle 3.1
388      * @throws moodle_exception
389      * @throws invalid_parameter_exception
390      */
391     public static function view_entry($id) {
392         global $DB, $USER;
394         $params = self::validate_parameters(self::view_entry_parameters(), array('id' => $id));
395         $id = $params['id'];
396         $warnings = array();
398         // Get and validate the glossary.
399         $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST);
400         list($glossary, $context, $course, $cm) = self::validate_glossary($entry->glossaryid);
402         if (!glossary_can_view_entry($entry, $cm)) {
403             throw new invalid_parameter_exception('invalidentry');
404         }
406         // Trigger view.
407         glossary_entry_view($entry, $context);
409         return array(
410             'status' => true,
411             'warnings' => $warnings
412         );
413     }
415     /**
416      * Returns the description of the external function return value.
417      *
418      * @return external_description
419      * @since Moodle 3.1
420      */
421     public static function view_entry_returns() {
422         return new external_single_structure(array(
423             'status' => new external_value(PARAM_BOOL, 'True on success'),
424             'warnings' => new external_warnings()
425         ));
426     }
428     /**
429      * Returns the description of the external function parameters.
430      *
431      * @return external_function_parameters
432      * @since Moodle 3.1
433      */
434     public static function get_entries_by_letter_parameters() {
435         return new external_function_parameters(array(
436             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
437             'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
438             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
439             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
440             'options' => new external_single_structure(array(
441                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
442                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
443             ), 'An array of options', VALUE_DEFAULT, array())
444         ));
445     }
447     /**
448      * Browse a glossary entries by letter.
449      *
450      * @param int $id The glossary ID.
451      * @param string $letter A letter, or a special keyword.
452      * @param int $from Start returning records from here.
453      * @param int $limit Number of records to return.
454      * @param array $options Array of options.
455      * @return array Containing count, entries and warnings.
456      * @since Moodle 3.1
457      * @throws moodle_exception
458      * @throws invalid_parameter_exception
459      */
460     public static function get_entries_by_letter($id, $letter, $from, $limit, $options) {
461         $params = self::validate_parameters(self::get_entries_by_letter_parameters(), array(
462             'id' => $id,
463             'letter' => $letter,
464             'from' => $from,
465             'limit' => $limit,
466             'options' => $options,
467         ));
468         $id = $params['id'];
469         $letter = $params['letter'];
470         $from = $params['from'];
471         $limit = $params['limit'];
472         $options = $params['options'];
473         $warnings = array();
475         // Get and validate the glossary.
476         list($glossary, $context) = self::validate_glossary($id);
478         // Validate the mode.
479         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
480         if (!in_array('letter', $modes)) {
481             throw new invalid_parameter_exception('invalidbrowsemode');
482         }
484         $entries = array();
485         list($records, $count) = glossary_get_entries_by_letter($glossary, $context, $letter, $from, $limit, $options);
486         foreach ($records as $key => $record) {
487             self::fill_entry_details($record, $context);
488             $entries[] = $record;
489         }
491         return array(
492             'count' => $count,
493             'entries' => $entries,
494             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
495             'warnings' => $warnings
496         );
497     }
499     /**
500      * Returns the description of the external function return value.
501      *
502      * @return external_description
503      * @since Moodle 3.1
504      */
505     public static function get_entries_by_letter_returns() {
506         return new external_single_structure(array(
507             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
508             'entries' => new external_multiple_structure(
509                 self::get_entry_return_structure()
510             ),
511             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
512             'warnings' => new external_warnings()
513         ));
514     }
516     /**
517      * Returns the description of the external function parameters.
518      *
519      * @return external_function_parameters
520      * @since Moodle 3.1
521      */
522     public static function get_entries_by_date_parameters() {
523         return new external_function_parameters(array(
524             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
525             'order' => new external_value(PARAM_ALPHA, 'Order the records by: \'CREATION\' or \'UPDATE\'.',
526                 VALUE_DEFAULT, 'UPDATE'),
527             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'DESC'),
528             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
529             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
530             'options' => new external_single_structure(array(
531                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
532                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
533             ), 'An array of options', VALUE_DEFAULT, array())
534         ));
535     }
537     /**
538      * Browse a glossary entries by date.
539      *
540      * @param int $id The glossary ID.
541      * @param string $order The way to order the records.
542      * @param string $sort The direction of the order.
543      * @param int $from Start returning records from here.
544      * @param int $limit Number of records to return.
545      * @param array $options Array of options.
546      * @return array Containing count, entries and warnings.
547      * @since Moodle 3.1
548      * @throws moodle_exception
549      * @throws invalid_parameter_exception
550      */
551     public static function get_entries_by_date($id, $order, $sort, $from, $limit, $options) {
552         $params = self::validate_parameters(self::get_entries_by_date_parameters(), array(
553             'id' => $id,
554             'order' => core_text::strtoupper($order),
555             'sort' => core_text::strtoupper($sort),
556             'from' => $from,
557             'limit' => $limit,
558             'options' => $options,
559         ));
560         $id = $params['id'];
561         $order = $params['order'];
562         $sort = $params['sort'];
563         $from = $params['from'];
564         $limit = $params['limit'];
565         $options = $params['options'];
566         $warnings = array();
568         if (!in_array($order, array('CREATION', 'UPDATE'))) {
569             throw new invalid_parameter_exception('invalidorder');
570         } else if (!in_array($sort, array('ASC', 'DESC'))) {
571             throw new invalid_parameter_exception('invalidsort');
572         }
574         // Get and validate the glossary.
575         list($glossary, $context) = self::validate_glossary($id);
577         // Validate the mode.
578         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
579         if (!in_array('date', $modes)) {
580             throw new invalid_parameter_exception('invalidbrowsemode');
581         }
583         $entries = array();
584         list($records, $count) = glossary_get_entries_by_date($glossary, $context, $order, $sort, $from, $limit, $options);
585         foreach ($records as $key => $record) {
586             self::fill_entry_details($record, $context);
587             $entries[] = $record;
588         }
590         return array(
591             'count' => $count,
592             'entries' => $entries,
593             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
594             'warnings' => $warnings
595         );
596     }
598     /**
599      * Returns the description of the external function return value.
600      *
601      * @return external_description
602      * @since Moodle 3.1
603      */
604     public static function get_entries_by_date_returns() {
605         return new external_single_structure(array(
606             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
607             'entries' => new external_multiple_structure(
608                 self::get_entry_return_structure()
609             ),
610             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
611             'warnings' => new external_warnings()
612         ));
613     }
615     /**
616      * Returns the description of the external function parameters.
617      *
618      * @return external_function_parameters
619      * @since Moodle 3.1
620      */
621     public static function get_categories_parameters() {
622         return new external_function_parameters(array(
623             'id' => new external_value(PARAM_INT, 'The glossary ID'),
624             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
625             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20)
626         ));
627     }
629     /**
630      * Get the categories of a glossary.
631      *
632      * @param int $id The glossary ID.
633      * @param int $from Start returning records from here.
634      * @param int $limit Number of records to return.
635      * @return array Containing count, categories and warnings.
636      * @since Moodle 3.1
637      * @throws moodle_exception
638      */
639     public static function get_categories($id, $from, $limit) {
640         $params = self::validate_parameters(self::get_categories_parameters(), array(
641             'id' => $id,
642             'from' => $from,
643             'limit' => $limit
644         ));
645         $id = $params['id'];
646         $from = $params['from'];
647         $limit = $params['limit'];
648         $warnings = array();
650         // Get and validate the glossary.
651         list($glossary, $context) = self::validate_glossary($id);
653         // Fetch the categories.
654         $categories = array();
655         list($records, $count) = glossary_get_categories($glossary, $from, $limit);
656         foreach ($records as $category) {
657             $category->name = external_format_string($category->name, $context->id);
658             $categories[] = $category;
659         }
661         return array(
662             'count' => $count,
663             'categories' => $categories,
664             'warnings' => array(),
665         );
666     }
668     /**
669      * Returns the description of the external function return value.
670      *
671      * @return external_description
672      * @since Moodle 3.1
673      */
674     public static function get_categories_returns() {
675         return new external_single_structure(array(
676             'count' => new external_value(PARAM_INT, 'The total number of records.'),
677             'categories' => new external_multiple_structure(
678                 new external_single_structure(array(
679                     'id' => new external_value(PARAM_INT, 'The category ID'),
680                     'glossaryid' => new external_value(PARAM_INT, 'The glossary ID'),
681                     'name' => new external_value(PARAM_RAW, 'The name of the category'),
682                     'usedynalink' => new external_value(PARAM_BOOL, 'Whether the category is automatically linked'),
683                 ))
684             ),
685             'warnings' => new external_warnings()
686         ));
687     }
689     /**
690      * Returns the description of the external function parameters.
691      *
692      * @return external_function_parameters
693      * @since Moodle 3.1
694      */
695     public static function get_entries_by_category_parameters() {
696         return new external_function_parameters(array(
697             'id' => new external_value(PARAM_INT, 'The glossary ID.'),
698             'categoryid' => new external_value(PARAM_INT, 'The category ID. Use \'' . GLOSSARY_SHOW_ALL_CATEGORIES . '\' for all' .
699                 ' categories, or \'' . GLOSSARY_SHOW_NOT_CATEGORISED . '\' for uncategorised entries.'),
700             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
701             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
702             'options' => new external_single_structure(array(
703                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
704                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
705             ), 'An array of options', VALUE_DEFAULT, array())
706         ));
707     }
709     /**
710      * Browse a glossary entries by category.
711      *
712      * @param int $id The glossary ID.
713      * @param int $categoryid The category ID.
714      * @param int $from Start returning records from here.
715      * @param int $limit Number of records to return.
716      * @param array $options Array of options.
717      * @return array Containing count, entries and warnings.
718      * @since Moodle 3.1
719      * @throws moodle_exception
720      * @throws invalid_parameter_exception
721      */
722     public static function get_entries_by_category($id, $categoryid, $from, $limit, $options) {
723         global $DB;
725         $params = self::validate_parameters(self::get_entries_by_category_parameters(), array(
726             'id' => $id,
727             'categoryid' => $categoryid,
728             'from' => $from,
729             'limit' => $limit,
730             'options' => $options,
731         ));
732         $id = $params['id'];
733         $categoryid = $params['categoryid'];
734         $from = $params['from'];
735         $limit = $params['limit'];
736         $options = $params['options'];
737         $warnings = array();
739         // Get and validate the glossary.
740         list($glossary, $context) = self::validate_glossary($id);
742         // Validate the mode.
743         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
744         if (!in_array('cat', $modes)) {
745             throw new invalid_parameter_exception('invalidbrowsemode');
746         }
748         // Validate the category.
749         if (in_array($categoryid, array(GLOSSARY_SHOW_ALL_CATEGORIES, GLOSSARY_SHOW_NOT_CATEGORISED))) {
750             // All good.
751         } else if (!$DB->record_exists('glossary_categories', array('id' => $categoryid, 'glossaryid' => $id))) {
752             throw new invalid_parameter_exception('invalidcategory');
753         }
755         // Fetching the entries.
756         $entries = array();
757         list($records, $count) = glossary_get_entries_by_category($glossary, $context, $categoryid, $from, $limit, $options);
758         foreach ($records as $key => $record) {
759             self::fill_entry_details($record, $context);
760             if ($record->categoryid === null) {
761                 $record->categoryid = GLOSSARY_SHOW_NOT_CATEGORISED;
762             }
763             if (isset($record->categoryname)) {
764                 $record->categoryname = external_format_string($record->categoryname, $context->id);
765             }
766             $entries[] = $record;
767         }
769         return array(
770             'count' => $count,
771             'entries' => $entries,
772             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
773             'warnings' => $warnings
774         );
775     }
777     /**
778      * Returns the description of the external function return value.
779      *
780      * @return external_description
781      * @since Moodle 3.1
782      */
783     public static function get_entries_by_category_returns() {
784         return new external_single_structure(array(
785             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
786             'entries' => new external_multiple_structure(
787                 self::get_entry_return_structure(true)
788             ),
789             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
790             'warnings' => new external_warnings()
791         ));
792     }
794     /**
795      * Returns the description of the external function parameters.
796      *
797      * @return external_function_parameters
798      * @since Moodle 3.1
799      */
800     public static function get_authors_parameters() {
801         return new external_function_parameters(array(
802             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
803             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
804             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
805             'options' => new external_single_structure(array(
806                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes self even if all of their entries' .
807                     ' require approval. When true, also includes authors only having entries pending approval.', VALUE_DEFAULT, 0)
808             ), 'An array of options', VALUE_DEFAULT, array())
809         ));
810     }
812     /**
813      * Get the authors of a glossary.
814      *
815      * @param int $id The glossary ID.
816      * @param int $from Start returning records from here.
817      * @param int $limit Number of records to return.
818      * @param array $options Array of options.
819      * @return array Containing count, authors and warnings.
820      * @since Moodle 3.1
821      * @throws moodle_exception
822      */
823     public static function get_authors($id, $from, $limit, $options) {
824         global $PAGE;
826         $params = self::validate_parameters(self::get_authors_parameters(), array(
827             'id' => $id,
828             'from' => $from,
829             'limit' => $limit,
830             'options' => $options,
831         ));
832         $id = $params['id'];
833         $from = $params['from'];
834         $limit = $params['limit'];
835         $options = $params['options'];
836         $warnings = array();
838         // Get and validate the glossary.
839         list($glossary, $context) = self::validate_glossary($id);
841         // Fetching the entries.
842         list($users, $count) = glossary_get_authors($glossary, $context, $limit, $from, $options);
844         $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
845         foreach ($users as $user) {
846             $userpicture = new user_picture($user);
847             $userpicture->size = 1;
849             $author = new stdClass();
850             $author->id = $user->id;
851             $author->fullname = fullname($user, $canviewfullnames);
852             $author->pictureurl = $userpicture->get_url($PAGE)->out(false);
853             $authors[] = $author;
854         }
855         $users->close();
857         return array(
858             'count' => $count,
859             'authors' => $authors,
860             'warnings' => array(),
861         );
862     }
864     /**
865      * Returns the description of the external function return value.
866      *
867      * @return external_description
868      * @since Moodle 3.1
869      */
870     public static function get_authors_returns() {
871         return new external_single_structure(array(
872             'count' => new external_value(PARAM_INT, 'The total number of records.'),
873             'authors' => new external_multiple_structure(
874                 new external_single_structure(array(
875                     'id' => new external_value(PARAM_INT, 'The user ID'),
876                     'fullname' => new external_value(PARAM_NOTAGS, 'The fullname'),
877                     'pictureurl' => new external_value(PARAM_URL, 'The picture URL'),
878                 ))
879             ),
880             'warnings' => new external_warnings()
881         ));
882     }
884     /**
885      * Returns the description of the external function parameters.
886      *
887      * @return external_function_parameters
888      * @since Moodle 3.1
889      */
890     public static function get_entries_by_author_parameters() {
891         return new external_function_parameters(array(
892             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
893             'letter' => new external_value(PARAM_ALPHA, 'First letter of firstname or lastname, or either keywords:'
894                 . ' \'ALL\' or \'SPECIAL\'.'),
895             'field' => new external_value(PARAM_ALPHA, 'Search and order using: \'FIRSTNAME\' or \'LASTNAME\'', VALUE_DEFAULT,
896                 'LASTNAME'),
897             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
898             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
899             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
900             'options' => new external_single_structure(array(
901                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
902                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
903             ), 'An array of options', VALUE_DEFAULT, array())
904         ));
905     }
907     /**
908      * Browse a glossary entries by author.
909      *
910      * @param int $id The glossary ID.
911      * @param string $letter A letter, or a special keyword.
912      * @param string $field The field to search from.
913      * @param string $sort The direction of the order.
914      * @param int $from Start returning records from here.
915      * @param int $limit Number of records to return.
916      * @param array $options Array of options.
917      * @return array Containing count, entries and warnings.
918      * @since Moodle 3.1
919      * @throws moodle_exception
920      * @throws invalid_parameter_exception
921      */
922     public static function get_entries_by_author($id, $letter, $field, $sort, $from, $limit, $options) {
923         $params = self::validate_parameters(self::get_entries_by_author_parameters(), array(
924             'id' => $id,
925             'letter' => $letter,
926             'field' => core_text::strtoupper($field),
927             'sort' => core_text::strtoupper($sort),
928             'from' => $from,
929             'limit' => $limit,
930             'options' => $options,
931         ));
932         $id = $params['id'];
933         $letter = $params['letter'];
934         $field = $params['field'];
935         $sort = $params['sort'];
936         $from = $params['from'];
937         $limit = $params['limit'];
938         $options = $params['options'];
939         $warnings = array();
941         if (!in_array($field, array('FIRSTNAME', 'LASTNAME'))) {
942             throw new invalid_parameter_exception('invalidfield');
943         } else if (!in_array($sort, array('ASC', 'DESC'))) {
944             throw new invalid_parameter_exception('invalidsort');
945         }
947         // Get and validate the glossary.
948         list($glossary, $context) = self::validate_glossary($id);
950         // Validate the mode.
951         $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
952         if (!in_array('author', $modes)) {
953             throw new invalid_parameter_exception('invalidbrowsemode');
954         }
956         // Fetching the entries.
957         $entries = array();
958         list($records, $count) = glossary_get_entries_by_author($glossary, $context, $letter, $field, $sort, $from, $limit,
959             $options);
960         foreach ($records as $key => $record) {
961             self::fill_entry_details($record, $context);
962             $entries[] = $record;
963         }
965         return array(
966             'count' => $count,
967             'entries' => $entries,
968             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
969             'warnings' => $warnings
970         );
971     }
973     /**
974      * Returns the description of the external function return value.
975      *
976      * @return external_description
977      * @since Moodle 3.1
978      */
979     public static function get_entries_by_author_returns() {
980         return new external_single_structure(array(
981             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
982             'entries' => new external_multiple_structure(
983                 self::get_entry_return_structure()
984             ),
985             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
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         }
1070         return array(
1071             'count' => $count,
1072             'entries' => $entries,
1073             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $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             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
1091             'warnings' => new external_warnings()
1092         ));
1093     }
1095     /**
1096      * Returns the description of the external function parameters.
1097      *
1098      * @return external_function_parameters
1099      * @since Moodle 3.1
1100      */
1101     public static function get_entries_by_search_parameters() {
1102         return new external_function_parameters(array(
1103             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1104             'query' => new external_value(PARAM_NOTAGS, 'The query string'),
1105             'fullsearch' => new external_value(PARAM_BOOL, 'The query', VALUE_DEFAULT, 1),
1106             'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1107                 'CONCEPT'),
1108             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1109             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1110             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1111             'options' => new external_single_structure(array(
1112                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1113                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1114             ), 'An array of options', VALUE_DEFAULT, array())
1115         ));
1116     }
1118     /**
1119      * Browse a glossary entries using the search.
1120      *
1121      * @param int $id The glossary ID.
1122      * @param string $query The search query.
1123      * @param bool $fullsearch Whether or not full search is required.
1124      * @param string $order The way to order the results.
1125      * @param string $sort The direction of the order.
1126      * @param int $from Start returning records from here.
1127      * @param int $limit Number of records to return.
1128      * @param array $options Array of options.
1129      * @return array Containing count, entries and warnings.
1130      * @since Moodle 3.1
1131      * @throws moodle_exception
1132      * @throws invalid_parameter_exception
1133      */
1134     public static function get_entries_by_search($id, $query, $fullsearch, $order, $sort, $from, $limit, $options) {
1135         $params = self::validate_parameters(self::get_entries_by_search_parameters(), array(
1136             'id' => $id,
1137             'query' => $query,
1138             'fullsearch' => $fullsearch,
1139             'order' => core_text::strtoupper($order),
1140             'sort' => core_text::strtoupper($sort),
1141             'from' => $from,
1142             'limit' => $limit,
1143             'options' => $options,
1144         ));
1145         $id = $params['id'];
1146         $query = $params['query'];
1147         $fullsearch = $params['fullsearch'];
1148         $order = $params['order'];
1149         $sort = $params['sort'];
1150         $from = $params['from'];
1151         $limit = $params['limit'];
1152         $options = $params['options'];
1153         $warnings = array();
1155         if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1156             throw new invalid_parameter_exception('invalidorder');
1157         } else if (!in_array($sort, array('ASC', 'DESC'))) {
1158             throw new invalid_parameter_exception('invalidsort');
1159         }
1161         // Get and validate the glossary.
1162         list($glossary, $context) = self::validate_glossary($id);
1164         // Fetching the entries.
1165         $entries = array();
1166         list($records, $count) = glossary_get_entries_by_search($glossary, $context, $query, $fullsearch, $order, $sort, $from,
1167             $limit, $options);
1168         foreach ($records as $key => $record) {
1169             self::fill_entry_details($record, $context);
1170             $entries[] = $record;
1171         }
1173         return array(
1174             'count' => $count,
1175             'entries' => $entries,
1176             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
1177             'warnings' => $warnings
1178         );
1179     }
1181     /**
1182      * Returns the description of the external function return value.
1183      *
1184      * @return external_description
1185      * @since Moodle 3.1
1186      */
1187     public static function get_entries_by_search_returns() {
1188         return new external_single_structure(array(
1189             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1190             'entries' => new external_multiple_structure(
1191                 self::get_entry_return_structure()
1192             ),
1193             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
1194             'warnings' => new external_warnings()
1195         ));
1196     }
1198     /**
1199      * Returns the description of the external function parameters.
1200      *
1201      * @return external_function_parameters
1202      * @since Moodle 3.1
1203      */
1204     public static function get_entries_by_term_parameters() {
1205         return new external_function_parameters(array(
1206             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1207             'term' => new external_value(PARAM_NOTAGS, 'The entry concept, or alias'),
1208             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1209             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1210             'options' => new external_single_structure(array(
1211                 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1212                     ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1213             ), 'An array of options', VALUE_DEFAULT, array())
1214         ));
1215     }
1217     /**
1218      * Browse a glossary entries using a term matching the concept or alias.
1219      *
1220      * @param int $id The glossary ID.
1221      * @param string $term The term.
1222      * @param int $from Start returning records from here.
1223      * @param int $limit Number of records to return.
1224      * @param array $options Array of options.
1225      * @return array Containing count, entries and warnings.
1226      * @since Moodle 3.1
1227      * @throws moodle_exception
1228      */
1229     public static function get_entries_by_term($id, $term, $from, $limit, $options) {
1230         $params = self::validate_parameters(self::get_entries_by_term_parameters(), array(
1231             'id' => $id,
1232             'term' => $term,
1233             'from' => $from,
1234             'limit' => $limit,
1235             'options' => $options,
1236         ));
1237         $id = $params['id'];
1238         $term = $params['term'];
1239         $from = $params['from'];
1240         $limit = $params['limit'];
1241         $options = $params['options'];
1242         $warnings = array();
1244         // Get and validate the glossary.
1245         list($glossary, $context) = self::validate_glossary($id);
1247         // Fetching the entries.
1248         $entries = array();
1249         list($records, $count) = glossary_get_entries_by_term($glossary, $context, $term, $from, $limit, $options);
1250         foreach ($records as $key => $record) {
1251             self::fill_entry_details($record, $context);
1252             $entries[] = $record;
1253         }
1255         return array(
1256             'count' => $count,
1257             'entries' => $entries,
1258             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
1259             'warnings' => $warnings
1260         );
1261     }
1263     /**
1264      * Returns the description of the external function return value.
1265      *
1266      * @return external_description
1267      * @since Moodle 3.1
1268      */
1269     public static function get_entries_by_term_returns() {
1270         return new external_single_structure(array(
1271             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1272             'entries' => new external_multiple_structure(
1273                 self::get_entry_return_structure()
1274             ),
1275             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
1276             'warnings' => new external_warnings()
1277         ));
1278     }
1280     /**
1281      * Returns the description of the external function parameters.
1282      *
1283      * @return external_function_parameters
1284      * @since Moodle 3.1
1285      */
1286     public static function get_entries_to_approve_parameters() {
1287         return new external_function_parameters(array(
1288             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1289             'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
1290             'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1291                 'CONCEPT'),
1292             'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1293             'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1294             'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1295             'options' => new external_single_structure(array(), 'An array of options', VALUE_DEFAULT, array())
1296         ));
1297     }
1299     /**
1300      * Browse a glossary entries using a term matching the concept or alias.
1301      *
1302      * @param int $id The glossary ID.
1303      * @param string $letter A letter, or a special keyword.
1304      * @param string $order The way to order the records.
1305      * @param string $sort The direction of the order.
1306      * @param int $from Start returning records from here.
1307      * @param int $limit Number of records to return.
1308      * @return array Containing count, entries and warnings.
1309      * @since Moodle 3.1
1310      * @throws moodle_exception
1311      */
1312     public static function get_entries_to_approve($id, $letter, $order, $sort, $from, $limit) {
1313         $params = self::validate_parameters(self::get_entries_to_approve_parameters(), array(
1314             'id' => $id,
1315             'letter' => $letter,
1316             'order' => $order,
1317             'sort' => $sort,
1318             'from' => $from,
1319             'limit' => $limit
1320         ));
1321         $id = $params['id'];
1322         $letter = $params['letter'];
1323         $order = $params['order'];
1324         $sort = $params['sort'];
1325         $from = $params['from'];
1326         $limit = $params['limit'];
1327         $warnings = array();
1329         // Get and validate the glossary.
1330         list($glossary, $context) = self::validate_glossary($id);
1332         // Check the permissions.
1333         require_capability('mod/glossary:approve', $context);
1335         // Fetching the entries.
1336         $entries = array();
1337         list($records, $count) = glossary_get_entries_to_approve($glossary, $context, $letter, $order, $sort, $from, $limit);
1338         foreach ($records as $key => $record) {
1339             self::fill_entry_details($record, $context);
1340             $entries[] = $record;
1341         }
1343         return array(
1344             'count' => $count,
1345             'entries' => $entries,
1346             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry', $entries),
1347             'warnings' => $warnings
1348         );
1349     }
1351     /**
1352      * Returns the description of the external function return value.
1353      *
1354      * @return external_description
1355      * @since Moodle 3.1
1356      */
1357     public static function get_entries_to_approve_returns() {
1358         return new external_single_structure(array(
1359             'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1360             'entries' => new external_multiple_structure(
1361                 self::get_entry_return_structure()
1362             ),
1363             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
1364             'warnings' => new external_warnings()
1365         ));
1366     }
1368     /**
1369      * Returns the description of the external function parameters.
1370      *
1371      * @return external_function_parameters
1372      * @since Moodle 3.1
1373      */
1374     public static function get_entry_by_id_parameters() {
1375         return new external_function_parameters(array(
1376             'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1377         ));
1378     }
1380     /**
1381      * Get an entry.
1382      *
1383      * @param int $id The entry ID.
1384      * @return array Containing entry and warnings.
1385      * @since Moodle 3.1
1386      * @throws moodle_exception
1387      * @throws invalid_parameter_exception
1388      */
1389     public static function get_entry_by_id($id) {
1390         global $DB, $USER;
1392         $params = self::validate_parameters(self::get_entry_by_id_parameters(), array('id' => $id));
1393         $id = $params['id'];
1394         $warnings = array();
1396         // Get and validate the glossary.
1397         $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST);
1398         list($glossary, $context) = self::validate_glossary($entry->glossaryid);
1400         if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) {
1401             throw new invalid_parameter_exception('invalidentry');
1402         }
1404         $entry = glossary_get_entry_by_id($id);
1405         self::fill_entry_details($entry, $context);
1407         return array(
1408             'entry' => $entry,
1409             'ratinginfo' => \core_rating\external\util::get_rating_info($glossary, $context, 'mod_glossary', 'entry',
1410                 array($entry)),
1411             'warnings' => $warnings
1412         );
1413     }
1415     /**
1416      * Returns the description of the external function return value.
1417      *
1418      * @return external_description
1419      * @since Moodle 3.1
1420      */
1421     public static function get_entry_by_id_returns() {
1422         return new external_single_structure(array(
1423             'entry' => self::get_entry_return_structure(),
1424             'ratinginfo' => \core_rating\external\util::external_ratings_structure(),
1425             'warnings' => new external_warnings()
1426         ));
1427     }
1429     /**
1430      * Returns the description of the external function parameters.
1431      *
1432      * @return external_function_parameters
1433      * @since Moodle 3.2
1434      */
1435     public static function add_entry_parameters() {
1436         return new external_function_parameters(array(
1437             'glossaryid' => new external_value(PARAM_INT, 'Glossary id'),
1438             'concept' => new external_value(PARAM_TEXT, 'Glossary concept'),
1439             'definition' => new external_value(PARAM_RAW, 'Glossary concept definition'),
1440             'definitionformat' => new external_format_value('definition'),
1441             'options' => new external_multiple_structure (
1442                 new external_single_structure(
1443                     array(
1444                         'name' => new external_value(PARAM_ALPHANUM,
1445                             'The allowed keys (value format) are:
1446                             inlineattachmentsid (int); the draft file area id for inline attachments
1447                             attachmentsid (int); the draft file area id for attachments
1448                             categories (comma separated int); comma separated category ids
1449                             aliases (comma separated str); comma separated aliases
1450                             usedynalink (bool); whether the entry should be automatically linked.
1451                             casesensitive (bool); whether the entry is case sensitive.
1452                             fullmatch (bool); whether to match whole words only.'),
1453                         'value' => new external_value(PARAM_RAW, 'the value of the option (validated inside the function)')
1454                     )
1455                 ), 'Optional settings', VALUE_DEFAULT, array()
1456             )
1457         ));
1458     }
1461     /**
1462      * Add a new entry to a given glossary.
1463      *
1464      * @param int $glossaryid the glosary id
1465      * @param string $concept    the glossary concept
1466      * @param string $definition the concept definition
1467      * @param int $definitionformat the concept definition format
1468      * @param array  $options    additional settings
1469      * @return array Containing entry and warnings.
1470      * @since Moodle 3.2
1471      * @throws moodle_exception
1472      * @throws invalid_parameter_exception
1473      */
1474     public static function add_entry($glossaryid, $concept, $definition, $definitionformat, $options = array()) {
1475         global $CFG;
1477         $params = self::validate_parameters(self::add_entry_parameters(), array(
1478             'glossaryid' => $glossaryid,
1479             'concept' => $concept,
1480             'definition' => $definition,
1481             'definitionformat' => $definitionformat,
1482             'options' => $options,
1483         ));
1484         $warnings = array();
1486         // Get and validate the glossary.
1487         list($glossary, $context, $course, $cm) = self::validate_glossary($params['glossaryid']);
1488         require_capability('mod/glossary:write', $context);
1490         if (!$glossary->allowduplicatedentries) {
1491             if (glossary_concept_exists($glossary, $params['concept'])) {
1492                 throw new moodle_exception('errconceptalreadyexists', 'glossary');
1493             }
1494         }
1496         // Prepare the entry object.
1497         $entry = new stdClass;
1498         $entry->id = null;
1499         $entry->aliases = '';
1500         $entry->usedynalink = $CFG->glossary_linkentries;
1501         $entry->casesensitive = $CFG->glossary_casesensitive;
1502         $entry->fullmatch = $CFG->glossary_fullmatch;
1503         $entry->concept = $params['concept'];
1504         $entry->definition_editor = array(
1505             'text' => $params['definition'],
1506             'format' => $params['definitionformat'],
1507         );
1508         // Options.
1509         foreach ($params['options'] as $option) {
1510             $name = trim($option['name']);
1511             switch ($name) {
1512                 case 'inlineattachmentsid':
1513                     $entry->definition_editor['itemid'] = clean_param($option['value'], PARAM_INT);
1514                     break;
1515                 case 'attachmentsid':
1516                     $entry->attachment_filemanager = clean_param($option['value'], PARAM_INT);
1517                     break;
1518                 case 'categories':
1519                     $entry->categories = clean_param($option['value'], PARAM_SEQUENCE);
1520                     $entry->categories = explode(',', $entry->categories);
1521                     break;
1522                 case 'aliases':
1523                     $entry->aliases = clean_param($option['value'], PARAM_NOTAGS);
1524                     // Convert to the expected format.
1525                     $entry->aliases = str_replace(",", "\n", $entry->aliases);
1526                     break;
1527                 case 'usedynalink':
1528                 case 'casesensitive':
1529                 case 'fullmatch':
1530                     // Only allow if linking is enabled.
1531                     if ($glossary->usedynalink) {
1532                         $entry->{$name} = clean_param($option['value'], PARAM_BOOL);
1533                     }
1534                     break;
1535                 default:
1536                     throw new moodle_exception('errorinvalidparam', 'webservice', '', $name);
1537             }
1538         }
1540         $entry = glossary_edit_entry($entry, $course, $cm, $glossary, $context);
1542         return array(
1543             'entryid' => $entry->id,
1544             'warnings' => $warnings
1545         );
1546     }
1548     /**
1549      * Returns the description of the external function return value.
1550      *
1551      * @return external_description
1552      * @since Moodle 3.2
1553      */
1554     public static function add_entry_returns() {
1555         return new external_single_structure(array(
1556             'entryid' => new external_value(PARAM_INT, 'New glossary entry ID'),
1557             'warnings' => new external_warnings()
1558         ));
1559     }