2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Glossary module external API.
20 * @package mod_glossary
22 * @copyright 2015 Costantino Cito <ccito@cvaconsulting.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->libdir . '/externallib.php');
30 require_once($CFG->dirroot . '/mod/glossary/lib.php');
33 * Glossary module external functions.
35 * @package mod_glossary
37 * @copyright 2015 Costantino Cito <ccito@cvaconsulting.com>
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 class mod_glossary_external extends external_api {
44 * Get the browse modes from the display format.
46 * This returns some of the terms that can be used when reporting a glossary being viewed.
48 * @param string $format The display format of the glossary.
49 * @return array Containing some of all of the following: letter, cat, date, author.
51 protected static function get_browse_modes_from_display_format($format) {
55 $dp = $DB->get_record('glossary_formats', array('name' => $format), '*', IGNORE_MISSING);
57 $formats = glossary_get_visible_tabs($dp);
60 // Always add 'letter'.
61 $modes = array('letter');
63 if (in_array('category', $formats)) {
66 if (in_array('date', $formats)) {
69 if (in_array('author', $formats)) {
77 * Get the return value of an entry.
79 * @param bool $includecat Whether the definition should include category info.
80 * @return external_definition
82 protected static function get_entry_return_structure($includecat = false) {
84 'id' => new external_value(PARAM_INT, 'The entry ID'),
85 'glossaryid' => new external_value(PARAM_INT, 'The glossary ID'),
86 'userid' => new external_value(PARAM_INT, 'Author ID'),
87 'userfullname' => new external_value(PARAM_NOTAGS, 'Author full name'),
88 'userpictureurl' => new external_value(PARAM_URL, 'Author picture'),
89 'concept' => new external_value(PARAM_RAW, 'The concept'),
90 'definition' => new external_value(PARAM_RAW, 'The definition'),
91 'definitionformat' => new external_format_value('definition'),
92 'definitiontrust' => new external_value(PARAM_BOOL, 'The definition trust flag'),
93 'attachment' => new external_value(PARAM_BOOL, 'Whether or not the entry has attachments'),
94 'attachments' => new external_files('attachments', VALUE_OPTIONAL),
95 'timecreated' => new external_value(PARAM_INT, 'Time created'),
96 'timemodified' => new external_value(PARAM_INT, 'Time modified'),
97 'teacherentry' => new external_value(PARAM_BOOL, 'The entry was created by a teacher, or equivalent.'),
98 'sourceglossaryid' => new external_value(PARAM_INT, 'The source glossary ID'),
99 'usedynalink' => new external_value(PARAM_BOOL, 'Whether the concept should be automatically linked'),
100 'casesensitive' => new external_value(PARAM_BOOL, 'When true, the matching is case sensitive'),
101 'fullmatch' => new external_value(PARAM_BOOL, 'When true, the matching is done on full words only'),
102 'approved' => new external_value(PARAM_BOOL, 'Whether the entry was approved'),
106 $params['categoryid'] = new external_value(PARAM_INT, 'The category ID. This may be' .
107 ' \''. GLOSSARY_SHOW_NOT_CATEGORISED . '\' when the entry is not categorised', VALUE_DEFAULT,
108 GLOSSARY_SHOW_NOT_CATEGORISED);
109 $params['categoryname'] = new external_value(PARAM_RAW, 'The category name. May be empty when the entry is' .
110 ' not categorised, or the request was limited to one category.', VALUE_DEFAULT, '');
113 return new external_single_structure($params);
117 * Fill in an entry object.
119 * This adds additional required fields for the external function to return.
121 * @param stdClass $entry The entry.
122 * @param context $context The context the entry belongs to.
125 protected static function fill_entry_details($entry, $context) {
127 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
129 // Format concept and definition.
130 $entry->concept = external_format_string($entry->concept, $context->id);
131 list($entry->definition, $entry->definitionformat) = external_format_text($entry->definition, $entry->definitionformat,
132 $context->id, 'mod_glossary', 'entry', $entry->id);
135 $user = mod_glossary_entry_query_builder::get_user_from_record($entry);
136 $userpicture = new user_picture($user);
137 $userpicture->size = 1;
138 $entry->userfullname = fullname($user, $canviewfullnames);
139 $entry->userpictureurl = $userpicture->get_url($PAGE)->out(false);
141 // Fetch attachments.
142 $entry->attachment = !empty($entry->attachment) ? 1 : 0;
143 $entry->attachments = array();
144 if ($entry->attachment) {
145 $entry->attachments = external_util::get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id);
150 * Validate a glossary via ID.
152 * @param int $id The glossary ID.
153 * @return array Contains glossary, context, course and cm.
155 protected static function validate_glossary($id) {
157 $glossary = $DB->get_record('glossary', array('id' => $id), '*', MUST_EXIST);
158 list($course, $cm) = get_course_and_cm_from_instance($glossary, 'glossary');
159 $context = context_module::instance($cm->id);
160 self::validate_context($context);
161 return array($glossary, $context, $course, $cm);
165 * Describes the parameters for get_glossaries_by_courses.
167 * @return external_external_function_parameters
170 public static function get_glossaries_by_courses_parameters() {
171 return new external_function_parameters (
173 'courseids' => new external_multiple_structure(
174 new external_value(PARAM_INT, 'course id'),
175 'Array of course IDs', VALUE_DEFAULT, array()
182 * Returns a list of glossaries in a provided list of courses.
184 * If no list is provided all glossaries that the user can view will be returned.
186 * @param array $courseids the course IDs.
187 * @return array of glossaries
190 public static function get_glossaries_by_courses($courseids = array()) {
191 $params = self::validate_parameters(self::get_glossaries_by_courses_parameters(), array('courseids' => $courseids));
195 $courseids = $params['courseids'];
197 if (empty($courseids)) {
198 $courses = enrol_get_my_courses();
199 $courseids = array_keys($courses);
202 // Array to store the glossaries to return.
203 $glossaries = array();
206 // Ensure there are courseids to loop through.
207 if (!empty($courseids)) {
208 list($courses, $warnings) = external_util::validate_courses($courseids, $courses);
210 // Get the glossaries in these courses, this function checks users visibility permissions.
211 $glossaries = get_all_instances_in_courses('glossary', $courses);
212 foreach ($glossaries as $glossary) {
213 $context = context_module::instance($glossary->coursemodule);
214 $glossary->name = external_format_string($glossary->name, $context->id);
215 list($glossary->intro, $glossary->introformat) = external_format_text($glossary->intro, $glossary->introformat,
216 $context->id, 'mod_glossary', 'intro', null);
217 $glossary->introfiles = external_util::get_area_files($context->id, 'mod_glossary', 'intro', false, false);
219 // Make sure we have a number of entries per page.
220 if (!$glossary->entbypage) {
221 $glossary->entbypage = $CFG->glossary_entbypage;
224 // Add the list of browsing modes.
225 if (!isset($modes[$glossary->displayformat])) {
226 $modes[$glossary->displayformat] = self::get_browse_modes_from_display_format($glossary->displayformat);
228 $glossary->browsemodes = $modes[$glossary->displayformat];
233 $result['glossaries'] = $glossaries;
234 $result['warnings'] = $warnings;
239 * Describes the get_glossaries_by_courses return value.
241 * @return external_single_structure
244 public static function get_glossaries_by_courses_returns() {
245 return new external_single_structure(array(
246 'glossaries' => new external_multiple_structure(
247 new external_single_structure(array(
248 'id' => new external_value(PARAM_INT, 'Glossary id'),
249 'coursemodule' => new external_value(PARAM_INT, 'Course module id'),
250 'course' => new external_value(PARAM_INT, 'Course id'),
251 'name' => new external_value(PARAM_RAW, 'Glossary name'),
252 'intro' => new external_value(PARAM_RAW, 'The Glossary intro'),
253 'introformat' => new external_format_value('intro'),
254 'introfiles' => new external_files('Files in the introduction text', VALUE_OPTIONAL),
255 'allowduplicatedentries' => new external_value(PARAM_INT, 'If enabled, multiple entries can have the' .
256 ' same concept name'),
257 'displayformat' => new external_value(PARAM_TEXT, 'Display format type'),
258 'mainglossary' => new external_value(PARAM_INT, 'If enabled this glossary is a main glossary.'),
259 'showspecial' => new external_value(PARAM_INT, 'If enabled, participants can browse the glossary by' .
260 ' special characters, such as @ and #'),
261 'showalphabet' => new external_value(PARAM_INT, 'If enabled, participants can browse the glossary by' .
262 ' letters of the alphabet'),
263 'showall' => new external_value(PARAM_INT, 'If enabled, participants can browse all entries at once'),
264 'allowcomments' => new external_value(PARAM_INT, 'If enabled, all participants with permission to' .
265 ' create comments will be able to add comments to glossary entries'),
266 'allowprintview' => new external_value(PARAM_INT, 'If enabled, students are provided with a link to a' .
267 ' printer-friendly version of the glossary. The link is always available to teachers'),
268 'usedynalink' => new external_value(PARAM_INT, 'If site-wide glossary auto-linking has been enabled' .
269 ' by an administrator and this checkbox is ticked, the entry will be automatically linked' .
270 ' wherever the concept words and phrases appear throughout the rest of the course.'),
271 'defaultapproval' => new external_value(PARAM_INT, 'If set to no, entries require approving by a' .
272 ' teacher before they are viewable by everyone.'),
273 'approvaldisplayformat' => new external_value(PARAM_TEXT, 'When approving glossary items you may wish' .
274 ' to use a different display format'),
275 'globalglossary' => new external_value(PARAM_INT, ''),
276 'entbypage' => new external_value(PARAM_INT, 'Entries shown per page'),
277 'editalways' => new external_value(PARAM_INT, 'Always allow editing'),
278 'rsstype' => new external_value(PARAM_INT, 'To enable the RSS feed for this activity, select either' .
279 ' concepts with author or concepts without author to be included in the feed'),
280 'rssarticles' => new external_value(PARAM_INT, 'This setting specifies the number of glossary entry' .
281 ' concepts to include in the RSS feed. Between 5 and 20 generally acceptable'),
282 'assessed' => new external_value(PARAM_INT, 'Aggregate type'),
283 'assesstimestart' => new external_value(PARAM_INT, 'Restrict rating to items created after this'),
284 'assesstimefinish' => new external_value(PARAM_INT, 'Restrict rating to items created before this'),
285 'scale' => new external_value(PARAM_INT, 'Scale ID'),
286 'timecreated' => new external_value(PARAM_INT, 'Time created'),
287 'timemodified' => new external_value(PARAM_INT, 'Time modified'),
288 'completionentries' => new external_value(PARAM_INT, 'Number of entries to complete'),
289 'section' => new external_value(PARAM_INT, 'Section'),
290 'visible' => new external_value(PARAM_INT, 'Visible'),
291 'groupmode' => new external_value(PARAM_INT, 'Group mode'),
292 'groupingid' => new external_value(PARAM_INT, 'Grouping ID'),
293 'browsemodes' => new external_multiple_structure(
294 new external_value(PARAM_ALPHA, 'Modes of browsing allowed')
298 'warnings' => new external_warnings())
303 * Returns the description of the external function parameters.
305 * @return external_function_parameters
308 public static function view_glossary_parameters() {
309 return new external_function_parameters(array(
310 'id' => new external_value(PARAM_INT, 'Glossary instance ID'),
311 'mode' => new external_value(PARAM_ALPHA, 'The mode in which the glossary is viewed'),
316 * Notify that the course module was viewed.
318 * @param int $id The glossary instance ID.
319 * @param string $mode The view mode.
320 * @return array of warnings and status result
322 * @throws moodle_exception
324 public static function view_glossary($id, $mode) {
325 $params = self::validate_parameters(self::view_glossary_parameters(), array(
330 $mode = $params['mode'];
333 // Get and validate the glossary.
334 list($glossary, $context, $course, $cm) = self::validate_glossary($id);
336 // Trigger module viewed event.
337 glossary_view($glossary, $course, $cm, $context, $mode);
341 'warnings' => $warnings
346 * Returns the description of the external function return value.
348 * @return external_description
351 public static function view_glossary_returns() {
352 return new external_single_structure(array(
353 'status' => new external_value(PARAM_BOOL, 'True on success'),
354 'warnings' => new external_warnings()
359 * Returns the description of the external function parameters.
361 * @return external_function_parameters
364 public static function view_entry_parameters() {
365 return new external_function_parameters(array(
366 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
371 * Notify that the entry was viewed.
373 * @param int $id The entry ID.
374 * @return array of warnings and status result
376 * @throws moodle_exception
377 * @throws invalid_parameter_exception
379 public static function view_entry($id) {
382 $params = self::validate_parameters(self::view_entry_parameters(), array('id' => $id));
386 // Get and validate the glossary.
387 $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST);
388 list($glossary, $context, $course, $cm) = self::validate_glossary($entry->glossaryid);
390 if (!glossary_can_view_entry($entry, $cm)) {
391 throw new invalid_parameter_exception('invalidentry');
395 glossary_entry_view($entry, $context);
399 'warnings' => $warnings
404 * Returns the description of the external function return value.
406 * @return external_description
409 public static function view_entry_returns() {
410 return new external_single_structure(array(
411 'status' => new external_value(PARAM_BOOL, 'True on success'),
412 'warnings' => new external_warnings()
417 * Returns the description of the external function parameters.
419 * @return external_function_parameters
422 public static function get_entries_by_letter_parameters() {
423 return new external_function_parameters(array(
424 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
425 'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
426 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
427 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
428 'options' => new external_single_structure(array(
429 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
430 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
431 ), 'An array of options', VALUE_DEFAULT, array())
436 * Browse a glossary entries by letter.
438 * @param int $id The glossary ID.
439 * @param string $letter A letter, or a special keyword.
440 * @param int $from Start returning records from here.
441 * @param int $limit Number of records to return.
442 * @param array $options Array of options.
443 * @return array Containing count, entries and warnings.
445 * @throws moodle_exception
446 * @throws invalid_parameter_exception
448 public static function get_entries_by_letter($id, $letter, $from, $limit, $options) {
449 $params = self::validate_parameters(self::get_entries_by_letter_parameters(), array(
454 'options' => $options,
457 $letter = $params['letter'];
458 $from = $params['from'];
459 $limit = $params['limit'];
460 $options = $params['options'];
463 // Get and validate the glossary.
464 list($glossary, $context) = self::validate_glossary($id);
466 // Validate the mode.
467 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
468 if (!in_array('letter', $modes)) {
469 throw new invalid_parameter_exception('invalidbrowsemode');
473 list($records, $count) = glossary_get_entries_by_letter($glossary, $context, $letter, $from, $limit, $options);
474 foreach ($records as $key => $record) {
475 self::fill_entry_details($record, $context);
476 $entries[] = $record;
481 'entries' => $entries,
482 'warnings' => $warnings
487 * Returns the description of the external function return value.
489 * @return external_description
492 public static function get_entries_by_letter_returns() {
493 return new external_single_structure(array(
494 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
495 'entries' => new external_multiple_structure(
496 self::get_entry_return_structure()
498 'warnings' => new external_warnings()
503 * Returns the description of the external function parameters.
505 * @return external_function_parameters
508 public static function get_entries_by_date_parameters() {
509 return new external_function_parameters(array(
510 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
511 'order' => new external_value(PARAM_ALPHA, 'Order the records by: \'CREATION\' or \'UPDATE\'.',
512 VALUE_DEFAULT, 'UPDATE'),
513 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'DESC'),
514 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
515 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
516 'options' => new external_single_structure(array(
517 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
518 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
519 ), 'An array of options', VALUE_DEFAULT, array())
524 * Browse a glossary entries by date.
526 * @param int $id The glossary ID.
527 * @param string $order The way to order the records.
528 * @param string $sort The direction of the order.
529 * @param int $from Start returning records from here.
530 * @param int $limit Number of records to return.
531 * @param array $options Array of options.
532 * @return array Containing count, entries and warnings.
534 * @throws moodle_exception
535 * @throws invalid_parameter_exception
537 public static function get_entries_by_date($id, $order, $sort, $from, $limit, $options) {
538 $params = self::validate_parameters(self::get_entries_by_date_parameters(), array(
540 'order' => core_text::strtoupper($order),
541 'sort' => core_text::strtoupper($sort),
544 'options' => $options,
547 $order = $params['order'];
548 $sort = $params['sort'];
549 $from = $params['from'];
550 $limit = $params['limit'];
551 $options = $params['options'];
554 if (!in_array($order, array('CREATION', 'UPDATE'))) {
555 throw new invalid_parameter_exception('invalidorder');
556 } else if (!in_array($sort, array('ASC', 'DESC'))) {
557 throw new invalid_parameter_exception('invalidsort');
560 // Get and validate the glossary.
561 list($glossary, $context) = self::validate_glossary($id);
563 // Validate the mode.
564 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
565 if (!in_array('date', $modes)) {
566 throw new invalid_parameter_exception('invalidbrowsemode');
570 list($records, $count) = glossary_get_entries_by_date($glossary, $context, $order, $sort, $from, $limit, $options);
571 foreach ($records as $key => $record) {
572 self::fill_entry_details($record, $context);
573 $entries[] = $record;
578 'entries' => $entries,
579 'warnings' => $warnings
584 * Returns the description of the external function return value.
586 * @return external_description
589 public static function get_entries_by_date_returns() {
590 return new external_single_structure(array(
591 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
592 'entries' => new external_multiple_structure(
593 self::get_entry_return_structure()
595 'warnings' => new external_warnings()
600 * Returns the description of the external function parameters.
602 * @return external_function_parameters
605 public static function get_categories_parameters() {
606 return new external_function_parameters(array(
607 'id' => new external_value(PARAM_INT, 'The glossary ID'),
608 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
609 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20)
614 * Get the categories of a glossary.
616 * @param int $id The glossary ID.
617 * @param int $from Start returning records from here.
618 * @param int $limit Number of records to return.
619 * @return array Containing count, categories and warnings.
621 * @throws moodle_exception
623 public static function get_categories($id, $from, $limit) {
624 $params = self::validate_parameters(self::get_categories_parameters(), array(
630 $from = $params['from'];
631 $limit = $params['limit'];
634 // Get and validate the glossary.
635 list($glossary, $context) = self::validate_glossary($id);
637 // Fetch the categories.
638 $categories = array();
639 list($records, $count) = glossary_get_categories($glossary, $from, $limit);
640 foreach ($records as $category) {
641 $category->name = external_format_string($category->name, $context->id);
642 $categories[] = $category;
647 'categories' => $categories,
648 'warnings' => array(),
653 * Returns the description of the external function return value.
655 * @return external_description
658 public static function get_categories_returns() {
659 return new external_single_structure(array(
660 'count' => new external_value(PARAM_INT, 'The total number of records.'),
661 'categories' => new external_multiple_structure(
662 new external_single_structure(array(
663 'id' => new external_value(PARAM_INT, 'The category ID'),
664 'glossaryid' => new external_value(PARAM_INT, 'The glossary ID'),
665 'name' => new external_value(PARAM_RAW, 'The name of the category'),
666 'usedynalink' => new external_value(PARAM_BOOL, 'Whether the category is automatically linked'),
669 'warnings' => new external_warnings()
674 * Returns the description of the external function parameters.
676 * @return external_function_parameters
679 public static function get_entries_by_category_parameters() {
680 return new external_function_parameters(array(
681 'id' => new external_value(PARAM_INT, 'The glossary ID.'),
682 'categoryid' => new external_value(PARAM_INT, 'The category ID. Use \'' . GLOSSARY_SHOW_ALL_CATEGORIES . '\' for all' .
683 ' categories, or \'' . GLOSSARY_SHOW_NOT_CATEGORISED . '\' for uncategorised entries.'),
684 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
685 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
686 'options' => new external_single_structure(array(
687 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
688 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
689 ), 'An array of options', VALUE_DEFAULT, array())
694 * Browse a glossary entries by category.
696 * @param int $id The glossary ID.
697 * @param int $categoryid The category ID.
698 * @param int $from Start returning records from here.
699 * @param int $limit Number of records to return.
700 * @param array $options Array of options.
701 * @return array Containing count, entries and warnings.
703 * @throws moodle_exception
704 * @throws invalid_parameter_exception
706 public static function get_entries_by_category($id, $categoryid, $from, $limit, $options) {
709 $params = self::validate_parameters(self::get_entries_by_category_parameters(), array(
711 'categoryid' => $categoryid,
714 'options' => $options,
717 $categoryid = $params['categoryid'];
718 $from = $params['from'];
719 $limit = $params['limit'];
720 $options = $params['options'];
723 // Get and validate the glossary.
724 list($glossary, $context) = self::validate_glossary($id);
726 // Validate the mode.
727 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
728 if (!in_array('cat', $modes)) {
729 throw new invalid_parameter_exception('invalidbrowsemode');
732 // Validate the category.
733 if (in_array($categoryid, array(GLOSSARY_SHOW_ALL_CATEGORIES, GLOSSARY_SHOW_NOT_CATEGORISED))) {
735 } else if (!$DB->record_exists('glossary_categories', array('id' => $categoryid, 'glossaryid' => $id))) {
736 throw new invalid_parameter_exception('invalidcategory');
739 // Fetching the entries.
741 list($records, $count) = glossary_get_entries_by_category($glossary, $context, $categoryid, $from, $limit, $options);
742 foreach ($records as $key => $record) {
743 self::fill_entry_details($record, $context);
744 if ($record->categoryid === null) {
745 $record->categoryid = GLOSSARY_SHOW_NOT_CATEGORISED;
747 if (isset($record->categoryname)) {
748 $record->categoryname = external_format_string($record->categoryname, $context->id);
750 $entries[] = $record;
755 'entries' => $entries,
756 'warnings' => $warnings
761 * Returns the description of the external function return value.
763 * @return external_description
766 public static function get_entries_by_category_returns() {
767 return new external_single_structure(array(
768 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
769 'entries' => new external_multiple_structure(
770 self::get_entry_return_structure(true)
772 'warnings' => new external_warnings()
777 * Returns the description of the external function parameters.
779 * @return external_function_parameters
782 public static function get_authors_parameters() {
783 return new external_function_parameters(array(
784 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
785 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
786 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
787 'options' => new external_single_structure(array(
788 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes self even if all of their entries' .
789 ' require approval. When true, also includes authors only having entries pending approval.', VALUE_DEFAULT, 0)
790 ), 'An array of options', VALUE_DEFAULT, array())
795 * Get the authors of a glossary.
797 * @param int $id The glossary ID.
798 * @param int $from Start returning records from here.
799 * @param int $limit Number of records to return.
800 * @param array $options Array of options.
801 * @return array Containing count, authors and warnings.
803 * @throws moodle_exception
805 public static function get_authors($id, $from, $limit, $options) {
808 $params = self::validate_parameters(self::get_authors_parameters(), array(
812 'options' => $options,
815 $from = $params['from'];
816 $limit = $params['limit'];
817 $options = $params['options'];
820 // Get and validate the glossary.
821 list($glossary, $context) = self::validate_glossary($id);
823 // Fetching the entries.
824 list($users, $count) = glossary_get_authors($glossary, $context, $limit, $from, $options);
826 $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
827 foreach ($users as $user) {
828 $userpicture = new user_picture($user);
829 $userpicture->size = 1;
831 $author = new stdClass();
832 $author->id = $user->id;
833 $author->fullname = fullname($user, $canviewfullnames);
834 $author->pictureurl = $userpicture->get_url($PAGE)->out(false);
835 $authors[] = $author;
841 'authors' => $authors,
842 'warnings' => array(),
847 * Returns the description of the external function return value.
849 * @return external_description
852 public static function get_authors_returns() {
853 return new external_single_structure(array(
854 'count' => new external_value(PARAM_INT, 'The total number of records.'),
855 'authors' => new external_multiple_structure(
856 new external_single_structure(array(
857 'id' => new external_value(PARAM_INT, 'The user ID'),
858 'fullname' => new external_value(PARAM_NOTAGS, 'The fullname'),
859 'pictureurl' => new external_value(PARAM_URL, 'The picture URL'),
862 'warnings' => new external_warnings()
867 * Returns the description of the external function parameters.
869 * @return external_function_parameters
872 public static function get_entries_by_author_parameters() {
873 return new external_function_parameters(array(
874 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
875 'letter' => new external_value(PARAM_ALPHA, 'First letter of firstname or lastname, or either keywords:'
876 . ' \'ALL\' or \'SPECIAL\'.'),
877 'field' => new external_value(PARAM_ALPHA, 'Search and order using: \'FIRSTNAME\' or \'LASTNAME\'', VALUE_DEFAULT,
879 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
880 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
881 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
882 'options' => new external_single_structure(array(
883 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
884 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
885 ), 'An array of options', VALUE_DEFAULT, array())
890 * Browse a glossary entries by author.
892 * @param int $id The glossary ID.
893 * @param string $letter A letter, or a special keyword.
894 * @param string $field The field to search from.
895 * @param string $sort The direction of the order.
896 * @param int $from Start returning records from here.
897 * @param int $limit Number of records to return.
898 * @param array $options Array of options.
899 * @return array Containing count, entries and warnings.
901 * @throws moodle_exception
902 * @throws invalid_parameter_exception
904 public static function get_entries_by_author($id, $letter, $field, $sort, $from, $limit, $options) {
905 $params = self::validate_parameters(self::get_entries_by_author_parameters(), array(
908 'field' => core_text::strtoupper($field),
909 'sort' => core_text::strtoupper($sort),
912 'options' => $options,
915 $letter = $params['letter'];
916 $field = $params['field'];
917 $sort = $params['sort'];
918 $from = $params['from'];
919 $limit = $params['limit'];
920 $options = $params['options'];
923 if (!in_array($field, array('FIRSTNAME', 'LASTNAME'))) {
924 throw new invalid_parameter_exception('invalidfield');
925 } else if (!in_array($sort, array('ASC', 'DESC'))) {
926 throw new invalid_parameter_exception('invalidsort');
929 // Get and validate the glossary.
930 list($glossary, $context) = self::validate_glossary($id);
932 // Validate the mode.
933 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
934 if (!in_array('author', $modes)) {
935 throw new invalid_parameter_exception('invalidbrowsemode');
938 // Fetching the entries.
940 list($records, $count) = glossary_get_entries_by_author($glossary, $context, $letter, $field, $sort, $from, $limit,
942 foreach ($records as $key => $record) {
943 self::fill_entry_details($record, $context);
944 $entries[] = $record;
949 'entries' => $entries,
950 'warnings' => $warnings
955 * Returns the description of the external function return value.
957 * @return external_description
960 public static function get_entries_by_author_returns() {
961 return new external_single_structure(array(
962 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
963 'entries' => new external_multiple_structure(
964 self::get_entry_return_structure()
966 'warnings' => new external_warnings()
971 * Returns the description of the external function parameters.
973 * @return external_function_parameters
976 public static function get_entries_by_author_id_parameters() {
977 return new external_function_parameters(array(
978 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
979 'authorid' => new external_value(PARAM_INT, 'The author ID'),
980 'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
982 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
983 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
984 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
985 'options' => new external_single_structure(array(
986 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
987 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
988 ), 'An array of options', VALUE_DEFAULT, array())
993 * Browse a glossary entries by author.
995 * @param int $id The glossary ID.
996 * @param int $authorid The author ID.
997 * @param string $order The way to order the results.
998 * @param string $sort The direction of the order.
999 * @param int $from Start returning records from here.
1000 * @param int $limit Number of records to return.
1001 * @param array $options Array of options.
1002 * @return array Containing count, entries and warnings.
1004 * @throws moodle_exception
1005 * @throws invalid_parameter_exception
1007 public static function get_entries_by_author_id($id, $authorid, $order, $sort, $from, $limit, $options) {
1008 $params = self::validate_parameters(self::get_entries_by_author_id_parameters(), array(
1010 'authorid' => $authorid,
1011 'order' => core_text::strtoupper($order),
1012 'sort' => core_text::strtoupper($sort),
1015 'options' => $options,
1017 $id = $params['id'];
1018 $authorid = $params['authorid'];
1019 $order = $params['order'];
1020 $sort = $params['sort'];
1021 $from = $params['from'];
1022 $limit = $params['limit'];
1023 $options = $params['options'];
1024 $warnings = array();
1026 if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1027 throw new invalid_parameter_exception('invalidorder');
1028 } else if (!in_array($sort, array('ASC', 'DESC'))) {
1029 throw new invalid_parameter_exception('invalidsort');
1032 // Get and validate the glossary.
1033 list($glossary, $context) = self::validate_glossary($id);
1035 // Validate the mode.
1036 $modes = self::get_browse_modes_from_display_format($glossary->displayformat);
1037 if (!in_array('author', $modes)) {
1038 throw new invalid_parameter_exception('invalidbrowsemode');
1041 // Fetching the entries.
1043 list($records, $count) = glossary_get_entries_by_author_id($glossary, $context, $authorid, $order, $sort, $from,
1045 foreach ($records as $key => $record) {
1046 self::fill_entry_details($record, $context);
1047 $entries[] = $record;
1052 'entries' => $entries,
1053 'warnings' => $warnings
1058 * Returns the description of the external function return value.
1060 * @return external_description
1063 public static function get_entries_by_author_id_returns() {
1064 return new external_single_structure(array(
1065 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1066 'entries' => new external_multiple_structure(
1067 self::get_entry_return_structure()
1069 'warnings' => new external_warnings()
1074 * Returns the description of the external function parameters.
1076 * @return external_function_parameters
1079 public static function get_entries_by_search_parameters() {
1080 return new external_function_parameters(array(
1081 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1082 'query' => new external_value(PARAM_NOTAGS, 'The query string'),
1083 'fullsearch' => new external_value(PARAM_BOOL, 'The query', VALUE_DEFAULT, 1),
1084 'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1086 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1087 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1088 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1089 'options' => new external_single_structure(array(
1090 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1091 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1092 ), 'An array of options', VALUE_DEFAULT, array())
1097 * Browse a glossary entries using the search.
1099 * @param int $id The glossary ID.
1100 * @param string $query The search query.
1101 * @param bool $fullsearch Whether or not full search is required.
1102 * @param string $order The way to order the results.
1103 * @param string $sort The direction of the order.
1104 * @param int $from Start returning records from here.
1105 * @param int $limit Number of records to return.
1106 * @param array $options Array of options.
1107 * @return array Containing count, entries and warnings.
1109 * @throws moodle_exception
1110 * @throws invalid_parameter_exception
1112 public static function get_entries_by_search($id, $query, $fullsearch, $order, $sort, $from, $limit, $options) {
1113 $params = self::validate_parameters(self::get_entries_by_search_parameters(), array(
1116 'fullsearch' => $fullsearch,
1117 'order' => core_text::strtoupper($order),
1118 'sort' => core_text::strtoupper($sort),
1121 'options' => $options,
1123 $id = $params['id'];
1124 $query = $params['query'];
1125 $fullsearch = $params['fullsearch'];
1126 $order = $params['order'];
1127 $sort = $params['sort'];
1128 $from = $params['from'];
1129 $limit = $params['limit'];
1130 $options = $params['options'];
1131 $warnings = array();
1133 if (!in_array($order, array('CONCEPT', 'CREATION', 'UPDATE'))) {
1134 throw new invalid_parameter_exception('invalidorder');
1135 } else if (!in_array($sort, array('ASC', 'DESC'))) {
1136 throw new invalid_parameter_exception('invalidsort');
1139 // Get and validate the glossary.
1140 list($glossary, $context) = self::validate_glossary($id);
1142 // Fetching the entries.
1144 list($records, $count) = glossary_get_entries_by_search($glossary, $context, $query, $fullsearch, $order, $sort, $from,
1146 foreach ($records as $key => $record) {
1147 self::fill_entry_details($record, $context);
1148 $entries[] = $record;
1153 'entries' => $entries,
1154 'warnings' => $warnings
1159 * Returns the description of the external function return value.
1161 * @return external_description
1164 public static function get_entries_by_search_returns() {
1165 return new external_single_structure(array(
1166 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1167 'entries' => new external_multiple_structure(
1168 self::get_entry_return_structure()
1170 'warnings' => new external_warnings()
1175 * Returns the description of the external function parameters.
1177 * @return external_function_parameters
1180 public static function get_entries_by_term_parameters() {
1181 return new external_function_parameters(array(
1182 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1183 'term' => new external_value(PARAM_NOTAGS, 'The entry concept, or alias'),
1184 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1185 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1186 'options' => new external_single_structure(array(
1187 'includenotapproved' => new external_value(PARAM_BOOL, 'When false, includes the non-approved entries created by' .
1188 ' the user. When true, also includes the ones that the user has the permission to approve.', VALUE_DEFAULT, 0)
1189 ), 'An array of options', VALUE_DEFAULT, array())
1194 * Browse a glossary entries using a term matching the concept or alias.
1196 * @param int $id The glossary ID.
1197 * @param string $term The term.
1198 * @param int $from Start returning records from here.
1199 * @param int $limit Number of records to return.
1200 * @param array $options Array of options.
1201 * @return array Containing count, entries and warnings.
1203 * @throws moodle_exception
1205 public static function get_entries_by_term($id, $term, $from, $limit, $options) {
1206 $params = self::validate_parameters(self::get_entries_by_term_parameters(), array(
1211 'options' => $options,
1213 $id = $params['id'];
1214 $term = $params['term'];
1215 $from = $params['from'];
1216 $limit = $params['limit'];
1217 $options = $params['options'];
1218 $warnings = array();
1220 // Get and validate the glossary.
1221 list($glossary, $context) = self::validate_glossary($id);
1223 // Fetching the entries.
1225 list($records, $count) = glossary_get_entries_by_term($glossary, $context, $term, $from, $limit, $options);
1226 foreach ($records as $key => $record) {
1227 self::fill_entry_details($record, $context);
1228 $entries[] = $record;
1233 'entries' => $entries,
1234 'warnings' => $warnings
1239 * Returns the description of the external function return value.
1241 * @return external_description
1244 public static function get_entries_by_term_returns() {
1245 return new external_single_structure(array(
1246 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1247 'entries' => new external_multiple_structure(
1248 self::get_entry_return_structure()
1250 'warnings' => new external_warnings()
1255 * Returns the description of the external function parameters.
1257 * @return external_function_parameters
1260 public static function get_entries_to_approve_parameters() {
1261 return new external_function_parameters(array(
1262 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1263 'letter' => new external_value(PARAM_ALPHA, 'A letter, or either keywords: \'ALL\' or \'SPECIAL\'.'),
1264 'order' => new external_value(PARAM_ALPHA, 'Order by: \'CONCEPT\', \'CREATION\' or \'UPDATE\'', VALUE_DEFAULT,
1266 'sort' => new external_value(PARAM_ALPHA, 'The direction of the order: \'ASC\' or \'DESC\'', VALUE_DEFAULT, 'ASC'),
1267 'from' => new external_value(PARAM_INT, 'Start returning records from here', VALUE_DEFAULT, 0),
1268 'limit' => new external_value(PARAM_INT, 'Number of records to return', VALUE_DEFAULT, 20),
1269 'options' => new external_single_structure(array(), 'An array of options', VALUE_DEFAULT, array())
1274 * Browse a glossary entries using a term matching the concept or alias.
1276 * @param int $id The glossary ID.
1277 * @param string $letter A letter, or a special keyword.
1278 * @param string $order The way to order the records.
1279 * @param string $sort The direction of the order.
1280 * @param int $from Start returning records from here.
1281 * @param int $limit Number of records to return.
1282 * @return array Containing count, entries and warnings.
1284 * @throws moodle_exception
1286 public static function get_entries_to_approve($id, $letter, $order, $sort, $from, $limit) {
1287 $params = self::validate_parameters(self::get_entries_to_approve_parameters(), array(
1289 'letter' => $letter,
1295 $id = $params['id'];
1296 $letter = $params['letter'];
1297 $order = $params['order'];
1298 $sort = $params['sort'];
1299 $from = $params['from'];
1300 $limit = $params['limit'];
1301 $warnings = array();
1303 // Get and validate the glossary.
1304 list($glossary, $context) = self::validate_glossary($id);
1306 // Check the permissions.
1307 require_capability('mod/glossary:approve', $context);
1309 // Fetching the entries.
1311 list($records, $count) = glossary_get_entries_to_approve($glossary, $context, $letter, $order, $sort, $from, $limit);
1312 foreach ($records as $key => $record) {
1313 self::fill_entry_details($record, $context);
1314 $entries[] = $record;
1319 'entries' => $entries,
1320 'warnings' => $warnings
1325 * Returns the description of the external function return value.
1327 * @return external_description
1330 public static function get_entries_to_approve_returns() {
1331 return new external_single_structure(array(
1332 'count' => new external_value(PARAM_INT, 'The total number of records matching the request.'),
1333 'entries' => new external_multiple_structure(
1334 self::get_entry_return_structure()
1336 'warnings' => new external_warnings()
1341 * Returns the description of the external function parameters.
1343 * @return external_function_parameters
1346 public static function get_entry_by_id_parameters() {
1347 return new external_function_parameters(array(
1348 'id' => new external_value(PARAM_INT, 'Glossary entry ID'),
1355 * @param int $id The entry ID.
1356 * @return array Containing entry and warnings.
1358 * @throws moodle_exception
1359 * @throws invalid_parameter_exception
1361 public static function get_entry_by_id($id) {
1364 $params = self::validate_parameters(self::get_entry_by_id_parameters(), array('id' => $id));
1365 $id = $params['id'];
1366 $warnings = array();
1368 // Get and validate the glossary.
1369 $entry = $DB->get_record('glossary_entries', array('id' => $id), '*', MUST_EXIST);
1370 list($glossary, $context) = self::validate_glossary($entry->glossaryid);
1372 if (empty($entry->approved) && $entry->userid != $USER->id && !has_capability('mod/glossary:approve', $context)) {
1373 throw new invalid_parameter_exception('invalidentry');
1376 $entry = glossary_get_entry_by_id($id);
1377 self::fill_entry_details($entry, $context);
1381 'warnings' => $warnings
1386 * Returns the description of the external function return value.
1388 * @return external_description
1391 public static function get_entry_by_id_returns() {
1392 return new external_single_structure(array(
1393 'entry' => self::get_entry_return_structure(),
1394 'warnings' => new external_warnings()