Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

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