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