Proyectos de Subversion Moodle

Rev

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