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