Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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