MDL-64656 core_tag: Return tags in modules and blog
[moodle.git] / mod / wiki / classes / external.php
CommitLineData
23cbaefb
DP
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Wiki module external API.
19 *
20 * @package mod_wiki
21 * @category external
22 * @copyright 2015 Dani Palou <dani@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @since Moodle 3.1
25 */
26
27defined('MOODLE_INTERNAL') || die;
28
29require_once($CFG->libdir . '/externallib.php');
30require_once($CFG->dirroot . '/mod/wiki/lib.php');
31require_once($CFG->dirroot . '/mod/wiki/locallib.php');
32
33/**
34 * Wiki module external functions.
35 *
36 * @package mod_wiki
37 * @category external
38 * @copyright 2015 Dani Palou <dani@moodle.com>
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 * @since Moodle 3.1
41 */
42class mod_wiki_external extends external_api {
43
44 /**
45 * Describes the parameters for get_wikis_by_courses.
46 *
47 * @return external_function_parameters
48 * @since Moodle 3.1
49 */
50 public static function get_wikis_by_courses_parameters() {
51 return new external_function_parameters (
52 array(
53 'courseids' => new external_multiple_structure(
54 new external_value(PARAM_INT, 'Course ID'), 'Array of course ids.', VALUE_DEFAULT, array()
55 ),
56 )
57 );
58 }
59
60 /**
61 * Returns a list of wikis in a provided list of courses,
62 * if no list is provided all wikis that the user can view will be returned.
63 *
64 * @param array $courseids The courses IDs.
65 * @return array Containing a list of warnings and a list of wikis.
66 * @since Moodle 3.1
67 */
68 public static function get_wikis_by_courses($courseids = array()) {
69
70 $returnedwikis = array();
71 $warnings = array();
72
73 $params = self::validate_parameters(self::get_wikis_by_courses_parameters(), array('courseids' => $courseids));
74
75 $mycourses = array();
76 if (empty($params['courseids'])) {
77 $mycourses = enrol_get_my_courses();
78 $params['courseids'] = array_keys($mycourses);
79 }
80
81 // Ensure there are courseids to loop through.
82 if (!empty($params['courseids'])) {
83
84 list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);
85
86 // Get the wikis in this course, this function checks users visibility permissions.
87 // We can avoid then additional validate_context calls.
88 $wikis = get_all_instances_in_courses('wiki', $courses);
89
90 foreach ($wikis as $wiki) {
91
92 $context = context_module::instance($wiki->coursemodule);
93
94 // Entry to return.
95 $module = array();
96
97 // First, we return information that any user can see in (or can deduce from) the web interface.
98 $module['id'] = $wiki->id;
99 $module['coursemodule'] = $wiki->coursemodule;
100 $module['course'] = $wiki->course;
101 $module['name'] = external_format_string($wiki->name, $context->id);
102
103 $viewablefields = [];
104 if (has_capability('mod/wiki:viewpage', $context)) {
105 list($module['intro'], $module['introformat']) =
d33c67bc 106 external_format_text($wiki->intro, $wiki->introformat, $context->id, 'mod_wiki', 'intro', null);
7ef49bd3 107 $module['introfiles'] = external_util::get_area_files($context->id, 'mod_wiki', 'intro', false, false);
23cbaefb
DP
108
109 $viewablefields = array('firstpagetitle', 'wikimode', 'defaultformat', 'forceformat', 'editbegin', 'editend',
110 'section', 'visible', 'groupmode', 'groupingid');
111 }
112
113 // Check additional permissions for returning optional private settings.
114 if (has_capability('moodle/course:manageactivities', $context)) {
115 $additionalfields = array('timecreated', 'timemodified');
116 $viewablefields = array_merge($viewablefields, $additionalfields);
117 }
118
119 foreach ($viewablefields as $field) {
120 $module[$field] = $wiki->{$field};
121 }
122
123 // Check if user can add new pages.
124 $module['cancreatepages'] = wiki_can_create_pages($context);
125
126 $returnedwikis[] = $module;
127 }
128 }
129
130 $result = array();
131 $result['wikis'] = $returnedwikis;
132 $result['warnings'] = $warnings;
133 return $result;
134 }
135
136 /**
137 * Describes the get_wikis_by_courses return value.
138 *
139 * @return external_single_structure
140 * @since Moodle 3.1
141 */
142 public static function get_wikis_by_courses_returns() {
143
144 return new external_single_structure(
145 array(
146 'wikis' => new external_multiple_structure(
147 new external_single_structure(
148 array(
149 'id' => new external_value(PARAM_INT, 'Wiki ID.'),
150 'coursemodule' => new external_value(PARAM_INT, 'Course module ID.'),
151 'course' => new external_value(PARAM_INT, 'Course ID.'),
152 'name' => new external_value(PARAM_RAW, 'Wiki name.'),
153 'intro' => new external_value(PARAM_RAW, 'Wiki intro.', VALUE_OPTIONAL),
154 'introformat' => new external_format_value('Wiki intro format.', VALUE_OPTIONAL),
7ef49bd3 155 'introfiles' => new external_files('Files in the introduction text', VALUE_OPTIONAL),
23cbaefb
DP
156 'timecreated' => new external_value(PARAM_INT, 'Time of creation.', VALUE_OPTIONAL),
157 'timemodified' => new external_value(PARAM_INT, 'Time of last modification.', VALUE_OPTIONAL),
158 'firstpagetitle' => new external_value(PARAM_RAW, 'First page title.', VALUE_OPTIONAL),
159 'wikimode' => new external_value(PARAM_TEXT, 'Wiki mode (individual, collaborative).', VALUE_OPTIONAL),
160 'defaultformat' => new external_value(PARAM_TEXT, 'Wiki\'s default format (html, creole, nwiki).',
161 VALUE_OPTIONAL),
162 'forceformat' => new external_value(PARAM_INT, '1 if format is forced, 0 otherwise.',
163 VALUE_OPTIONAL),
164 'editbegin' => new external_value(PARAM_INT, 'Edit begin.', VALUE_OPTIONAL),
165 'editend' => new external_value(PARAM_INT, 'Edit end.', VALUE_OPTIONAL),
166 'section' => new external_value(PARAM_INT, 'Course section ID.', VALUE_OPTIONAL),
167 'visible' => new external_value(PARAM_INT, '1 if visible, 0 otherwise.', VALUE_OPTIONAL),
168 'groupmode' => new external_value(PARAM_INT, 'Group mode.', VALUE_OPTIONAL),
169 'groupingid' => new external_value(PARAM_INT, 'Group ID.', VALUE_OPTIONAL),
170 'cancreatepages' => new external_value(PARAM_BOOL, 'True if user can create pages.'),
171 ), 'Wikis'
172 )
173 ),
174 'warnings' => new external_warnings(),
175 )
176 );
177 }
178
557b58b0
DP
179 /**
180 * Describes the parameters for view_wiki.
181 *
182 * @return external_function_parameters
183 * @since Moodle 3.1
184 */
185 public static function view_wiki_parameters() {
186 return new external_function_parameters (
187 array(
188 'wikiid' => new external_value(PARAM_INT, 'Wiki instance ID.')
189 )
190 );
191 }
192
193 /**
194 * Trigger the course module viewed event and update the module completion status.
195 *
196 * @param int $wikiid The wiki instance ID.
197 * @return array of warnings and status result.
198 * @since Moodle 3.1
199 */
200 public static function view_wiki($wikiid) {
201
202 $params = self::validate_parameters(self::view_wiki_parameters(),
203 array(
204 'wikiid' => $wikiid
205 ));
206 $warnings = array();
207
208 // Get wiki instance.
209 if (!$wiki = wiki_get_wiki($params['wikiid'])) {
210 throw new moodle_exception('incorrectwikiid', 'wiki');
211 }
212
213 // Permission validation.
214 list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki');
215 $context = context_module::instance($cm->id);
216 self::validate_context($context);
217
218 // Check if user can view this wiki.
219 // We don't use wiki_user_can_view because it requires to have a valid subwiki for the user.
220 if (!has_capability('mod/wiki:viewpage', $context)) {
221 throw new moodle_exception('cannotviewpage', 'wiki');
222 }
223
224 // Trigger course_module_viewed event and completion.
225 wiki_view($wiki, $course, $cm, $context);
226
227 $result = array();
228 $result['status'] = true;
229 $result['warnings'] = $warnings;
230 return $result;
231 }
232
233 /**
234 * Describes the view_wiki return value.
235 *
236 * @return external_single_structure
237 * @since Moodle 3.1
238 */
239 public static function view_wiki_returns() {
240 return new external_single_structure(
241 array(
242 'status' => new external_value(PARAM_BOOL, 'Status: true if success.'),
243 'warnings' => new external_warnings()
244 )
245 );
246 }
247
248 /**
249 * Describes the parameters for view_page.
250 *
251 * @return external_function_parameters
252 * @since Moodle 3.1
253 */
254 public static function view_page_parameters() {
255 return new external_function_parameters (
256 array(
257 'pageid' => new external_value(PARAM_INT, 'Wiki page ID.'),
258 )
259 );
260 }
261
262 /**
263 * Trigger the page viewed event and update the module completion status.
264 *
265 * @param int $pageid The page ID.
266 * @return array of warnings and status result.
267 * @since Moodle 3.1
268 * @throws moodle_exception if page is not valid.
269 */
270 public static function view_page($pageid) {
271
272 $params = self::validate_parameters(self::view_page_parameters(),
273 array(
274 'pageid' => $pageid
275 ));
276 $warnings = array();
277
278 // Get wiki page.
279 if (!$page = wiki_get_page($params['pageid'])) {
280 throw new moodle_exception('incorrectpageid', 'wiki');
281 }
282
283 // Get wiki instance.
284 if (!$wiki = wiki_get_wiki_from_pageid($params['pageid'])) {
285 throw new moodle_exception('incorrectwikiid', 'wiki');
286 }
287
288 // Permission validation.
289 list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki');
290 $context = context_module::instance($cm->id);
291 self::validate_context($context);
292
293 // Check if user can view this wiki.
294 if (!$subwiki = wiki_get_subwiki($page->subwikiid)) {
295 throw new moodle_exception('incorrectsubwikiid', 'wiki');
296 }
297 if (!wiki_user_can_view($subwiki, $wiki)) {
298 throw new moodle_exception('cannotviewpage', 'wiki');
299 }
300
301 // Trigger page_viewed event and completion.
302 wiki_page_view($wiki, $page, $course, $cm, $context);
303
304 $result = array();
305 $result['status'] = true;
306 $result['warnings'] = $warnings;
307 return $result;
308 }
309
310 /**
311 * Describes the view_page return value.
312 *
313 * @return external_single_structure
314 * @since Moodle 3.1
315 */
316 public static function view_page_returns() {
317 return new external_single_structure(
318 array(
319 'status' => new external_value(PARAM_BOOL, 'Status: true if success.'),
320 'warnings' => new external_warnings()
321 )
322 );
323 }
324
44f1b701
DP
325 /**
326 * Describes the parameters for get_subwikis.
327 *
328 * @return external_function_parameters
329 * @since Moodle 3.1
330 */
331 public static function get_subwikis_parameters() {
332 return new external_function_parameters (
333 array(
334 'wikiid' => new external_value(PARAM_INT, 'Wiki instance ID.')
335 )
336 );
337 }
338
339 /**
340 * Returns the list of subwikis the user can see in a specific wiki.
341 *
342 * @param int $wikiid The wiki instance ID.
343 * @return array Containing a list of warnings and a list of subwikis.
344 * @since Moodle 3.1
345 */
346 public static function get_subwikis($wikiid) {
347 global $USER;
348
349 $warnings = array();
350
351 $params = self::validate_parameters(self::get_subwikis_parameters(), array('wikiid' => $wikiid));
352
353 // Get wiki instance.
354 if (!$wiki = wiki_get_wiki($params['wikiid'])) {
355 throw new moodle_exception('incorrectwikiid', 'wiki');
356 }
357
358 // Validate context and capabilities.
359 list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki');
360 $context = context_module::instance($cm->id);
361 self::validate_context($context);
362 require_capability('mod/wiki:viewpage', $context);
363
364 $returnedsubwikis = wiki_get_visible_subwikis($wiki, $cm, $context);
365 foreach ($returnedsubwikis as $subwiki) {
366 $subwiki->canedit = wiki_user_can_edit($subwiki);
367 }
368
369 $result = array();
370 $result['subwikis'] = $returnedsubwikis;
371 $result['warnings'] = $warnings;
372 return $result;
373 }
374
375 /**
376 * Describes the get_subwikis return value.
377 *
378 * @return external_single_structure
379 * @since Moodle 3.1
380 */
381 public static function get_subwikis_returns() {
382 return new external_single_structure(
383 array(
384 'subwikis' => new external_multiple_structure(
385 new external_single_structure(
386 array(
387 'id' => new external_value(PARAM_INT, 'Subwiki ID.'),
388 'wikiid' => new external_value(PARAM_INT, 'Wiki ID.'),
389 'groupid' => new external_value(PARAM_RAW, 'Group ID.'),
390 'userid' => new external_value(PARAM_INT, 'User ID.'),
391 'canedit' => new external_value(PARAM_BOOL, 'True if user can edit the subwiki.'),
392 ), 'Subwikis'
393 )
394 ),
395 'warnings' => new external_warnings(),
396 )
397 );
398 }
399
96abf9af
DP
400 /**
401 * Describes the parameters for get_subwiki_pages.
402 *
403 * @return external_function_parameters
404 * @since Moodle 3.1
405 */
406 public static function get_subwiki_pages_parameters() {
407 return new external_function_parameters (
408 array(
409 'wikiid' => new external_value(PARAM_INT, 'Wiki instance ID.'),
410 'groupid' => new external_value(PARAM_INT, 'Subwiki\'s group ID, -1 means current group. It will be ignored'
411 . ' if the wiki doesn\'t use groups.', VALUE_DEFAULT, -1),
412 'userid' => new external_value(PARAM_INT, 'Subwiki\'s user ID, 0 means current user. It will be ignored'
413 .' in collaborative wikis.', VALUE_DEFAULT, 0),
414 'options' => new external_single_structure(
415 array(
416 'sortby' => new external_value(PARAM_ALPHA,
417 'Field to sort by (id, title, ...).', VALUE_DEFAULT, 'title'),
418 'sortdirection' => new external_value(PARAM_ALPHA,
419 'Sort direction: ASC or DESC.', VALUE_DEFAULT, 'ASC'),
420 'includecontent' => new external_value(PARAM_INT,
2a84fae0 421 'Include each page contents or just the contents size.', VALUE_DEFAULT, 1),
96abf9af
DP
422 ), 'Options', VALUE_DEFAULT, array()),
423 )
424 );
425 }
426
427 /**
428 * Returns the list of pages from a specific subwiki.
429 *
430 * @param int $wikiid The wiki instance ID.
431 * @param int $groupid The group ID. If not defined, use current group.
432 * @param int $userid The user ID. If not defined, use current user.
433 * @param array $options Several options like sort by, sort direction, ...
434 * @return array Containing a list of warnings and a list of pages.
435 * @since Moodle 3.1
436 */
437 public static function get_subwiki_pages($wikiid, $groupid = -1, $userid = 0, $options = array()) {
96abf9af
DP
438
439 $returnedpages = array();
440 $warnings = array();
441
442 $params = self::validate_parameters(self::get_subwiki_pages_parameters(),
443 array(
444 'wikiid' => $wikiid,
445 'groupid' => $groupid,
446 'userid' => $userid,
447 'options' => $options
448 )
449 );
450
451 // Get wiki instance.
452 if (!$wiki = wiki_get_wiki($params['wikiid'])) {
453 throw new moodle_exception('incorrectwikiid', 'wiki');
454 }
455 list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki');
456 $context = context_module::instance($cm->id);
457 self::validate_context($context);
458
62e20cfe
DP
459 // Determine groupid and userid to use.
460 list($groupid, $userid) = self::determine_group_and_user($cm, $wiki, $params['groupid'], $params['userid']);
96abf9af 461
62e20cfe
DP
462 // Get subwiki and validate it.
463 $subwiki = wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid);
96abf9af 464
62e20cfe
DP
465 if ($subwiki === false) {
466 throw new moodle_exception('cannotviewpage', 'wiki');
467 } else if ($subwiki->id != -1) {
96abf9af
DP
468
469 // Set sort param.
470 $options = $params['options'];
471 if (!empty($options['sortby'])) {
472 if ($options['sortdirection'] != 'ASC' && $options['sortdirection'] != 'DESC') {
473 // Invalid sort direction. Use default.
474 $options['sortdirection'] = 'ASC';
475 }
476 $sort = $options['sortby'] . ' ' . $options['sortdirection'];
477 }
478
479 $pages = wiki_get_page_list($subwiki->id, $sort);
480 $caneditpages = wiki_user_can_edit($subwiki);
481 $firstpage = wiki_get_first_page($subwiki->id);
482
483 foreach ($pages as $page) {
484 $retpage = array(
485 'id' => $page->id,
486 'subwikiid' => $page->subwikiid,
487 'title' => external_format_string($page->title, $context->id),
488 'timecreated' => $page->timecreated,
489 'timemodified' => $page->timemodified,
490 'timerendered' => $page->timerendered,
491 'userid' => $page->userid,
492 'pageviews' => $page->pageviews,
493 'readonly' => $page->readonly,
494 'caneditpage' => $caneditpages,
6c344ff2
JL
495 'firstpage' => $page->id == $firstpage->id,
496 'tags' => \core_tag\external\util::get_item_tags('mod_wiki', 'wiki_pages', $page->id),
96abf9af
DP
497 );
498
b1be9b20
DP
499 // Refresh page cached content if needed.
500 if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
501 if ($content = wiki_refresh_cachedcontent($page)) {
502 $page = $content['page'];
96abf9af 503 }
b1be9b20
DP
504 }
505 list($cachedcontent, $contentformat) = external_format_text(
506 $page->cachedcontent, FORMAT_HTML, $context->id, 'mod_wiki', 'attachments', $subwiki->id);
96abf9af 507
b1be9b20
DP
508 if ($options['includecontent']) {
509 // Return the page content.
510 $retpage['cachedcontent'] = $cachedcontent;
511 $retpage['contentformat'] = $contentformat;
512 } else {
513 // Return the size of the content.
514 if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
515 $retpage['contentsize'] = mb_strlen($cachedcontent, '8bit');
516 } else {
517 $retpage['contentsize'] = strlen($cachedcontent);
518 }
96abf9af
DP
519 }
520
521 $returnedpages[] = $retpage;
522 }
96abf9af
DP
523 }
524
525 $result = array();
526 $result['pages'] = $returnedpages;
527 $result['warnings'] = $warnings;
528 return $result;
529 }
530
531 /**
532 * Describes the get_subwiki_pages return value.
533 *
534 * @return external_single_structure
535 * @since Moodle 3.1
536 */
537 public static function get_subwiki_pages_returns() {
538
539 return new external_single_structure(
540 array(
541 'pages' => new external_multiple_structure(
542 new external_single_structure(
543 array(
544 'id' => new external_value(PARAM_INT, 'Page ID.'),
545 'subwikiid' => new external_value(PARAM_INT, 'Page\'s subwiki ID.'),
546 'title' => new external_value(PARAM_RAW, 'Page title.'),
547 'timecreated' => new external_value(PARAM_INT, 'Time of creation.'),
548 'timemodified' => new external_value(PARAM_INT, 'Time of last modification.'),
549 'timerendered' => new external_value(PARAM_INT, 'Time of last renderization.'),
550 'userid' => new external_value(PARAM_INT, 'ID of the user that last modified the page.'),
551 'pageviews' => new external_value(PARAM_INT, 'Number of times the page has been viewed.'),
552 'readonly' => new external_value(PARAM_INT, '1 if readonly, 0 otherwise.'),
553 'caneditpage' => new external_value(PARAM_BOOL, 'True if user can edit the page.'),
554 'firstpage' => new external_value(PARAM_BOOL, 'True if it\'s the first page.'),
555 'cachedcontent' => new external_value(PARAM_RAW, 'Page contents.', VALUE_OPTIONAL),
556 'contentformat' => new external_format_value('cachedcontent', VALUE_OPTIONAL),
b1be9b20
DP
557 'contentsize' => new external_value(PARAM_INT, 'Size of page contents in bytes (doesn\'t include'.
558 ' size of attached files).', VALUE_OPTIONAL),
6c344ff2
JL
559 'tags' => new external_multiple_structure(
560 \core_tag\external\tag_item_exporter::get_read_structure(), 'Tags', VALUE_OPTIONAL
561 ),
96abf9af
DP
562 ), 'Pages'
563 )
564 ),
565 'warnings' => new external_warnings(),
566 )
567 );
568 }
569
5d94e343
DP
570 /**
571 * Describes the parameters for get_page_contents.
572 *
573 * @return external_function_parameters
574 * @since Moodle 3.1
575 */
576 public static function get_page_contents_parameters() {
577 return new external_function_parameters (
578 array(
579 'pageid' => new external_value(PARAM_INT, 'Page ID.')
580 )
581 );
582 }
583
584 /**
585 * Get a page contents.
586 *
587 * @param int $pageid The page ID.
588 * @return array of warnings and page data.
589 * @since Moodle 3.1
590 */
591 public static function get_page_contents($pageid) {
592
593 $params = self::validate_parameters(self::get_page_contents_parameters(),
594 array(
595 'pageid' => $pageid
596 )
597 );
598 $warnings = array();
599
600 // Get wiki page.
601 if (!$page = wiki_get_page($params['pageid'])) {
602 throw new moodle_exception('incorrectpageid', 'wiki');
603 }
604
605 // Get wiki instance.
606 if (!$wiki = wiki_get_wiki_from_pageid($params['pageid'])) {
607 throw new moodle_exception('incorrectwikiid', 'wiki');
608 }
609
610 // Permission validation.
611 $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course);
612 $context = context_module::instance($cm->id);
613 self::validate_context($context);
614
615 // Check if user can view this wiki.
616 if (!$subwiki = wiki_get_subwiki($page->subwikiid)) {
617 throw new moodle_exception('incorrectsubwikiid', 'wiki');
618 }
619 if (!wiki_user_can_view($subwiki, $wiki)) {
620 throw new moodle_exception('cannotviewpage', 'wiki');
621 }
622
623 $returnedpage = array();
624 $returnedpage['id'] = $page->id;
625 $returnedpage['wikiid'] = $wiki->id;
626 $returnedpage['subwikiid'] = $page->subwikiid;
627 $returnedpage['groupid'] = $subwiki->groupid;
628 $returnedpage['userid'] = $subwiki->userid;
629 $returnedpage['title'] = $page->title;
6c344ff2 630 $returnedpage['tags'] = \core_tag\external\util::get_item_tags('mod_wiki', 'wiki_pages', $page->id);
5d94e343
DP
631
632 // Refresh page cached content if needed.
633 if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
634 if ($content = wiki_refresh_cachedcontent($page)) {
635 $page = $content['page'];
636 }
637 }
638
639 list($returnedpage['cachedcontent'], $returnedpage['contentformat']) = external_format_text(
640 $page->cachedcontent, FORMAT_HTML, $context->id, 'mod_wiki', 'attachments', $subwiki->id);
641 $returnedpage['caneditpage'] = wiki_user_can_edit($subwiki);
642
7f98de7d
DP
643 // Get page version.
644 $version = wiki_get_current_version($page->id);
645 if (!empty($version)) {
646 $returnedpage['version'] = $version->version;
647 }
648
5d94e343
DP
649 $result = array();
650 $result['page'] = $returnedpage;
651 $result['warnings'] = $warnings;
652 return $result;
653 }
654
655 /**
656 * Describes the get_page_contents return value.
657 *
658 * @return external_single_structure
659 * @since Moodle 3.1
660 */
661 public static function get_page_contents_returns() {
662 return new external_single_structure(
663 array(
664 'page' => new external_single_structure(
665 array(
666 'id' => new external_value(PARAM_INT, 'Page ID.'),
667 'wikiid' => new external_value(PARAM_INT, 'Page\'s wiki ID.'),
668 'subwikiid' => new external_value(PARAM_INT, 'Page\'s subwiki ID.'),
669 'groupid' => new external_value(PARAM_INT, 'Page\'s group ID.'),
670 'userid' => new external_value(PARAM_INT, 'Page\'s user ID.'),
671 'title' => new external_value(PARAM_RAW, 'Page title.'),
672 'cachedcontent' => new external_value(PARAM_RAW, 'Page contents.'),
673 'contentformat' => new external_format_value('cachedcontent', VALUE_OPTIONAL),
7f98de7d
DP
674 'caneditpage' => new external_value(PARAM_BOOL, 'True if user can edit the page.'),
675 'version' => new external_value(PARAM_INT, 'Latest version of the page.', VALUE_OPTIONAL),
6c344ff2
JL
676 'tags' => new external_multiple_structure(
677 \core_tag\external\tag_item_exporter::get_read_structure(), 'Tags', VALUE_OPTIONAL
678 ),
5d94e343
DP
679 ), 'Page'
680 ),
681 'warnings' => new external_warnings()
682 )
683 );
684 }
685
62e20cfe
DP
686 /**
687 * Describes the parameters for get_subwiki_files.
688 *
689 * @return external_function_parameters
690 * @since Moodle 3.1
691 */
692 public static function get_subwiki_files_parameters() {
693 return new external_function_parameters (
694 array(
695 'wikiid' => new external_value(PARAM_INT, 'Wiki instance ID.'),
696 'groupid' => new external_value(PARAM_INT, 'Subwiki\'s group ID, -1 means current group. It will be ignored'
697 . ' if the wiki doesn\'t use groups.', VALUE_DEFAULT, -1),
698 'userid' => new external_value(PARAM_INT, 'Subwiki\'s user ID, 0 means current user. It will be ignored'
699 .' in collaborative wikis.', VALUE_DEFAULT, 0)
700 )
701 );
702 }
703
704 /**
705 * Returns the list of files from a specific subwiki.
706 *
707 * @param int $wikiid The wiki instance ID.
708 * @param int $groupid The group ID. If not defined, use current group.
709 * @param int $userid The user ID. If not defined, use current user.
710 * @return array Containing a list of warnings and a list of files.
711 * @since Moodle 3.1
712 * @throws moodle_exception
713 */
714 public static function get_subwiki_files($wikiid, $groupid = -1, $userid = 0) {
715
716 $returnedfiles = array();
717 $warnings = array();
718
719 $params = self::validate_parameters(self::get_subwiki_files_parameters(),
720 array(
721 'wikiid' => $wikiid,
722 'groupid' => $groupid,
723 'userid' => $userid
724 )
725 );
726
727 // Get wiki instance.
728 if (!$wiki = wiki_get_wiki($params['wikiid'])) {
729 throw new moodle_exception('incorrectwikiid', 'wiki');
730 }
731 list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki');
732 $context = context_module::instance($cm->id);
733 self::validate_context($context);
734
735 // Determine groupid and userid to use.
736 list($groupid, $userid) = self::determine_group_and_user($cm, $wiki, $params['groupid'], $params['userid']);
737
738 // Get subwiki and validate it.
739 $subwiki = wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid);
740
741 // Get subwiki based on group and user.
742 if ($subwiki === false) {
743 throw new moodle_exception('cannotviewfiles', 'wiki');
744 } else if ($subwiki->id != -1) {
745 // The subwiki exists, let's get the files.
14590070 746 $returnedfiles = external_util::get_area_files($context->id, 'mod_wiki', 'attachments', $subwiki->id);
62e20cfe
DP
747 }
748
749 $result = array();
750 $result['files'] = $returnedfiles;
751 $result['warnings'] = $warnings;
752 return $result;
753 }
754
755 /**
756 * Describes the get_subwiki_pages return value.
757 *
758 * @return external_single_structure
759 * @since Moodle 3.1
760 */
761 public static function get_subwiki_files_returns() {
762
763 return new external_single_structure(
764 array(
14590070 765 'files' => new external_files('Files'),
62e20cfe
DP
766 'warnings' => new external_warnings(),
767 )
768 );
769 }
770
771 /**
772 * Utility function for determining the groupid and userid to use.
773 *
774 * @param stdClass $cm The course module.
775 * @param stdClass $wiki The wiki.
776 * @param int $groupid Group ID. If not defined, use current group.
777 * @param int $userid User ID. If not defined, use current user.
778 * @return array Array containing the courseid and userid.
779 * @since Moodle 3.1
780 */
781 protected static function determine_group_and_user($cm, $wiki, $groupid = -1, $userid = 0) {
782 global $USER;
783
784 $currentgroup = groups_get_activity_group($cm);
785 if ($currentgroup === false) {
786 // Activity doesn't use groups.
787 $groupid = 0;
788 } else if ($groupid == -1) {
789 // Use current group.
790 $groupid = !empty($currentgroup) ? $currentgroup : 0;
791 }
792
793 // Determine user.
794 if ($wiki->wikimode == 'collaborative') {
795 // Collaborative wikis don't use userid in subwikis.
796 $userid = 0;
797 } else if (empty($userid)) {
798 // Use current user.
799 $userid = $USER->id;
800 }
801
802 return array($groupid, $userid);
803 }
804
20dca621
PFO
805 /**
806 * Describes the parameters for get_page_for_editing.
807 *
808 * @return external_function_parameters
809 * @since Moodle 3.1
810 */
811 public static function get_page_for_editing_parameters() {
812 return new external_function_parameters (
813 array(
814 'pageid' => new external_value(PARAM_INT, 'Page ID to edit.'),
c13c21b9
PFO
815 'section' => new external_value(PARAM_RAW, 'Section page title.', VALUE_DEFAULT, null),
816 'lockonly' => new external_value(PARAM_BOOL, 'Just renew lock and not return content.', VALUE_DEFAULT, false)
20dca621
PFO
817 )
818 );
819 }
820
821 /**
822 * Locks and retrieves info of page-section to be edited.
823 *
824 * @param int $pageid The page ID.
825 * @param string $section Section page title.
c13c21b9 826 * @param boolean $lockonly If true: Just renew lock and not return content.
20dca621
PFO
827 * @return array of warnings and page data.
828 * @since Moodle 3.1
829 */
c13c21b9 830 public static function get_page_for_editing($pageid, $section = null, $lockonly = false) {
20dca621
PFO
831 global $USER;
832
833 $params = self::validate_parameters(self::get_page_for_editing_parameters(),
834 array(
835 'pageid' => $pageid,
c13c21b9
PFO
836 'section' => $section,
837 'lockonly' => $lockonly
20dca621
PFO
838 )
839 );
840
841 $warnings = array();
842
843 // Get wiki page.
844 if (!$page = wiki_get_page($params['pageid'])) {
845 throw new moodle_exception('incorrectpageid', 'wiki');
846 }
847
848 // Get wiki instance.
849 if (!$wiki = wiki_get_wiki_from_pageid($params['pageid'])) {
850 throw new moodle_exception('incorrectwikiid', 'wiki');
851 }
852
853 // Get subwiki instance.
854 if (!$subwiki = wiki_get_subwiki($page->subwikiid)) {
855 throw new moodle_exception('incorrectsubwikiid', 'wiki');
856 }
857
858 // Permission validation.
859 $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course);
860 $context = context_module::instance($cm->id);
861 self::validate_context($context);
862
863 if (!wiki_user_can_edit($subwiki)) {
864 throw new moodle_exception('cannoteditpage', 'wiki');
865 }
866
867 if (!wiki_set_lock($params['pageid'], $USER->id, $params['section'], true)) {
868 throw new moodle_exception('pageislocked', 'wiki');
869 }
870
871 $version = wiki_get_current_version($page->id);
872 if (empty($version)) {
873 throw new moodle_exception('versionerror', 'wiki');
874 }
875
20dca621 876 $pagesection = array();
20dca621
PFO
877 $pagesection['version'] = $version->version;
878
c13c21b9
PFO
879 // Content requested to be returned.
880 if (!$lockonly) {
881 if (!is_null($params['section'])) {
882 $content = wiki_parser_proxy::get_section($version->content, $version->contentformat, $params['section']);
883 } else {
884 $content = $version->content;
885 }
886
887 $pagesection['content'] = $content;
888 $pagesection['contentformat'] = $version->contentformat;
889 }
890
20dca621
PFO
891 $result = array();
892 $result['pagesection'] = $pagesection;
893 $result['warnings'] = $warnings;
894 return $result;
895
896 }
897
898 /**
899 * Describes the get_page_for_editing return value.
900 *
901 * @return external_single_structure
902 * @since Moodle 3.1
903 */
904 public static function get_page_for_editing_returns() {
905 return new external_single_structure(
906 array(
907 'pagesection' => new external_single_structure(
908 array(
c13c21b9
PFO
909 'content' => new external_value(PARAM_RAW, 'The contents of the page-section to be edited.',
910 VALUE_OPTIONAL),
911 'contentformat' => new external_value(PARAM_TEXT, 'Format of the original content of the page.',
912 VALUE_OPTIONAL),
20dca621
PFO
913 'version' => new external_value(PARAM_INT, 'Latest version of the page.'),
914 'warnings' => new external_warnings()
915 )
916 )
917 )
918 );
919 }
920
a6b6f0d2
PFO
921 /**
922 * Describes the parameters for new_page.
923 *
924 * @return external_function_parameters
925 * @since Moodle 3.1
926 */
927 public static function new_page_parameters() {
928 return new external_function_parameters (
929 array(
930 'title' => new external_value(PARAM_TEXT, 'New page title.'),
931 'content' => new external_value(PARAM_RAW, 'Page contents.'),
932 'contentformat' => new external_value(PARAM_TEXT, 'Page contents format. If an invalid format is provided, default
933 wiki format is used.', VALUE_DEFAULT, null),
934 'subwikiid' => new external_value(PARAM_INT, 'Page\'s subwiki ID.', VALUE_DEFAULT, null),
935 'wikiid' => new external_value(PARAM_INT, 'Page\'s wiki ID. Used if subwiki does not exists.', VALUE_DEFAULT,
936 null),
937 'userid' => new external_value(PARAM_INT, 'Subwiki\'s user ID. Used if subwiki does not exists.', VALUE_DEFAULT,
938 null),
939 'groupid' => new external_value(PARAM_INT, 'Subwiki\'s group ID. Used if subwiki does not exists.', VALUE_DEFAULT,
940 null)
941 )
942 );
943 }
944
945 /**
946 * Creates a new page.
947 *
948 * @param string $title New page title.
949 * @param string $content Page contents.
950 * @param int $contentformat Page contents format. If an invalid format is provided, default wiki format is used.
951 * @param int $subwikiid The Subwiki ID where to store the page.
952 * @param int $wikiid Page\'s wiki ID. Used if subwiki does not exists.
953 * @param int $userid Subwiki\'s user ID. Used if subwiki does not exists.
954 * @param int $groupid Subwiki\'s group ID. Used if subwiki does not exists.
955 * @return array of warnings and page data.
956 * @since Moodle 3.1
957 */
958 public static function new_page($title, $content, $contentformat = null, $subwikiid = null, $wikiid = null, $userid = null,
959 $groupid = null) {
960 global $USER;
961
962 $params = self::validate_parameters(self::new_page_parameters(),
963 array(
964 'title' => $title,
965 'content' => $content,
966 'contentformat' => $contentformat,
967 'subwikiid' => $subwikiid,
968 'wikiid' => $wikiid,
969 'userid' => $userid,
970 'groupid' => $groupid
971 )
972 );
973
974 $warnings = array();
975
976 // Get wiki and subwiki instances.
977 if (!empty($params['subwikiid'])) {
978 if (!$subwiki = wiki_get_subwiki($params['subwikiid'])) {
979 throw new moodle_exception('incorrectsubwikiid', 'wiki');
980 }
981
982 if (!$wiki = wiki_get_wiki($subwiki->wikiid)) {
983 throw new moodle_exception('incorrectwikiid', 'wiki');
984 }
985
986 // Permission validation.
987 $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course);
988 $context = context_module::instance($cm->id);
989 self::validate_context($context);
990
991 } else {
992 if (!$wiki = wiki_get_wiki($params['wikiid'])) {
993 throw new moodle_exception('incorrectwikiid', 'wiki');
994 }
995
996 // Permission validation.
997 $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course);
998 $context = context_module::instance($cm->id);
999 self::validate_context($context);
1000
1001 // Determine groupid and userid to use.
1002 list($groupid, $userid) = self::determine_group_and_user($cm, $wiki, $params['groupid'], $params['userid']);
1003
1004 // Get subwiki and validate it.
1005 $subwiki = wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid);
1006
1007 if ($subwiki === false) {
1008 // User cannot view page.
1009 throw new moodle_exception('cannoteditpage', 'wiki');
1010 } else if ($subwiki->id < 0) {
1011 // Subwiki needed to check edit permissions.
1012 if (!wiki_user_can_edit($subwiki)) {
1013 throw new moodle_exception('cannoteditpage', 'wiki');
1014 }
1015
1016 // Subwiki does not exists and it can be created.
1017 $swid = wiki_add_subwiki($wiki->id, $groupid, $userid);
1018 if (!$subwiki = wiki_get_subwiki($swid)) {
1019 throw new moodle_exception('incorrectsubwikiid', 'wiki');
1020 }
1021 }
1022 }
1023
1024 // Subwiki needed to check edit permissions.
1025 if (!wiki_user_can_edit($subwiki)) {
1026 throw new moodle_exception('cannoteditpage', 'wiki');
1027 }
1028
1029 if ($page = wiki_get_page_by_title($subwiki->id, $params['title'])) {
1030 throw new moodle_exception('pageexists', 'wiki');
1031 }
1032
1033 // Ignore invalid formats and use default instead.
1034 if (!$params['contentformat'] || $wiki->forceformat) {
1035 $params['contentformat'] = $wiki->defaultformat;
1036 } else {
1037 $formats = wiki_get_formats();
1038 if (!in_array($params['contentformat'], $formats)) {
1039 $params['contentformat'] = $wiki->defaultformat;
1040 }
1041 }
1042
1043 $newpageid = wiki_create_page($subwiki->id, $params['title'], $params['contentformat'], $USER->id);
1044
1045 if (!$page = wiki_get_page($newpageid)) {
1046 throw new moodle_exception('incorrectpageid', 'wiki');
1047 }
1048
1049 // Save content.
1050 $save = wiki_save_page($page, $params['content'], $USER->id);
1051
1052 if (!$save) {
1053 throw new moodle_exception('savingerror', 'wiki');
1054 }
1055
1056 $result = array();
1057 $result['pageid'] = $page->id;
1058 $result['warnings'] = $warnings;
1059 return $result;
1060 }
1061
1062 /**
1063 * Describes the new_page return value.
1064 *
1065 * @return external_single_structure
1066 * @since Moodle 3.1
1067 */
1068 public static function new_page_returns() {
1069 return new external_single_structure(
1070 array(
1071 'pageid' => new external_value(PARAM_INT, 'New page id.'),
1072 'warnings' => new external_warnings()
1073 )
1074 );
1075 }
1076
cf16f6ed
PFO
1077 /**
1078 * Describes the parameters for edit_page.
1079 *
1080 * @return external_function_parameters
1081 * @since Moodle 3.1
1082 */
1083 public static function edit_page_parameters() {
1084 return new external_function_parameters (
1085 array(
1086 'pageid' => new external_value(PARAM_INT, 'Page ID.'),
1087 'content' => new external_value(PARAM_RAW, 'Page contents.'),
3b40103c 1088 'section' => new external_value(PARAM_RAW, 'Section page title.', VALUE_DEFAULT, null)
cf16f6ed
PFO
1089 )
1090 );
1091 }
1092
1093 /**
1094 * Edit a page contents.
1095 *
1096 * @param int $pageid The page ID.
1097 * @param string $content Page contents.
1098 * @param int $section Section to be edited.
1099 * @return array of warnings and page data.
1100 * @since Moodle 3.1
1101 */
1102 public static function edit_page($pageid, $content, $section = null) {
1103 global $USER;
1104
1105 $params = self::validate_parameters(self::edit_page_parameters(),
1106 array(
1107 'pageid' => $pageid,
1108 'content' => $content,
1109 'section' => $section
1110 )
1111 );
1112 $warnings = array();
1113
1114 // Get wiki page.
1115 if (!$page = wiki_get_page($params['pageid'])) {
1116 throw new moodle_exception('incorrectpageid', 'wiki');
1117 }
1118
1119 // Get wiki instance.
1120 if (!$wiki = wiki_get_wiki_from_pageid($params['pageid'])) {
1121 throw new moodle_exception('incorrectwikiid', 'wiki');
1122 }
1123
1124 // Get subwiki instance.
1125 if (!$subwiki = wiki_get_subwiki($page->subwikiid)) {
1126 throw new moodle_exception('incorrectsubwikiid', 'wiki');
1127 }
1128
1129 // Permission validation.
1130 $cm = get_coursemodule_from_instance('wiki', $wiki->id, $wiki->course);
1131 $context = context_module::instance($cm->id);
1132 self::validate_context($context);
1133
1134 if (!wiki_user_can_edit($subwiki)) {
1135 throw new moodle_exception('cannoteditpage', 'wiki');
1136 }
1137
1138 if (wiki_is_page_section_locked($page->id, $USER->id, $params['section'])) {
1139 throw new moodle_exception('pageislocked', 'wiki');
1140 }
1141
1142 // Save content.
1143 if (!is_null($params['section'])) {
1144 $version = wiki_get_current_version($page->id);
1145 $content = wiki_parser_proxy::get_section($version->content, $version->contentformat, $params['section'], false);
1146 if (!$content) {
1147 throw new moodle_exception('invalidsection', 'wiki');
1148 }
1149
1150 $save = wiki_save_section($page, $params['section'], $params['content'], $USER->id);
1151 } else {
1152 $save = wiki_save_page($page, $params['content'], $USER->id);
1153 }
1154
1155 wiki_delete_locks($page->id, $USER->id, $params['section']);
1156
1157 if (!$save) {
1158 throw new moodle_exception('savingerror', 'wiki');
1159 }
1160
1161 $result = array();
1162 $result['pageid'] = $page->id;
1163 $result['warnings'] = $warnings;
1164 return $result;
1165 }
1166
1167 /**
1168 * Describes the edit_page return value.
1169 *
1170 * @return external_single_structure
1171 * @since Moodle 3.1
1172 */
1173 public static function edit_page_returns() {
1174 return new external_single_structure(
1175 array(
1176 'pageid' => new external_value(PARAM_INT, 'Edited page id.'),
1177 'warnings' => new external_warnings()
1178 )
1179 );
1180 }
1181
23cbaefb 1182}